-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathrsa_parallel_naive_approach.cpp
More file actions
198 lines (154 loc) · 4.78 KB
/
rsa_parallel_naive_approach.cpp
File metadata and controls
198 lines (154 loc) · 4.78 KB
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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
#include <iostream>
#include <cmath>
#include <omp.h>
#include <cstring>
#include <cstdlib>
#include <fstream>
using namespace std;
#define MESSAGE_SIZE 100000
// In order to determine whether two numbers are co-prime (relatively prime), we can check
// whether their gcd (greatest common divisor) is greater than 1. The gcd can be calculated by Euclid's algorithm:
unsigned int gcd(unsigned int a, unsigned int b)
{
unsigned int x;
while (b)
{
x = a % b;
a = b;
b = x;
}
return a;
}
int main(int argc, char *argv[])
{
unsigned int message[MESSAGE_SIZE];
long double encryptedMessage[MESSAGE_SIZE];
// Checking the number of input has to be passed by the user
if (argc != 3)
{
printf("Usuage: ./<executable> <input_file> <thread_count>\n");
return -1;
}
// Getting values from the argument
ifstream fInput(argv[1]);
int thread_count = atoi(argv[2]);
// Checking whether the input file exists in the directory or not
if (!fInput)
{
printf("Error opening the input file.\n");
return -1;
}
unsigned int iP, iQ, iD, iE, iN, iTotientN;
fInput >> iP >> iQ;
int i = 0;
char cItem;
while(fInput >> cItem)
{
message[i] = cItem - '0';
i++;
}
// Done reading from the file
fInput.close();
// Store the starting time of the program
double startTime = omp_get_wtime();
cout << "P: " << iP << endl;
cout << "Q: " << iQ << endl;
// Print plain text
/*cout << "------ Plaintext message -------" << endl;
for (i = 0; i < MESSAGE_SIZE; i++)
cout << message[i] << ' ';
cout << endl;*/
//Compute iN, iE, and iD
iN = iP * iQ;
iP -= 1;
iQ -= 1;
iTotientN = iP * iQ;
iE = 7;
while(i < (iN - 1))
{
if(gcd(iE, iTotientN) == 1)
break;
iE++;
}
i = 1;
while(i < iN)
{
iD = (iE * i - 1) % iTotientN;
if(!iD)
{
iD = i;
break;
}
i++;
}
// RSA Encryption
cout << "\n------ Encrypted message -------" << endl;
cout << "E: " << iE << endl;
cout << "N: " << iN << endl;
// Computing partition variables
int iChunk = iE / thread_count;
int iChunkRemainder = iE % thread_count;
int startIndex, endIndex;
long double dTemp;
for(i = 0; i < MESSAGE_SIZE; i++)
{
encryptedMessage[i] = 1;
//Getting into the parallel region
#pragma omp parallel firstprivate(startIndex, endIndex) num_threads(thread_count)
{
int myRank = omp_get_thread_num(); //What thread am I?
dTemp = 1;
// Computing two varibles to buffer through the array which are derivatives from myRank variable
startIndex = myRank * iChunk;
if(iChunkRemainder && (startIndex + iChunk) > iE)
endIndex = iChunkRemainder;
else if (iChunkRemainder && myRank == thread_count - 1 && (startIndex + iChunk) < iE)
endIndex = startIndex + iChunk + iChunkRemainder;
else
endIndex = startIndex + iChunk;
for(int index = startIndex; index < endIndex; index++)
dTemp = dTemp * message[i];
/*if(i < 2)
cout << "Start Index: " << startIndex << " | End Index: " << endIndex << " | Process: " << myRank << " | Result: " << dTemp << endl;*/
encryptedMessage[i] = encryptedMessage[i] * dTemp;
}
encryptedMessage[i] = fmod(encryptedMessage[i], iN);
cout << encryptedMessage[i] << " ";
}
// RSA Decryption
cout << "\n\n------ Decrypted message -------" << endl;
cout << "D: " << iD << endl;
cout << "N: " << iN << endl;
// Computing partition variables
iChunk = iD / thread_count;
iChunkRemainder = iD % thread_count;
for(i = 0; i < MESSAGE_SIZE; i++)
{
long double decryptedText = 1;
//Getting into the parallel region
#pragma omp parallel firstprivate(startIndex, endIndex) num_threads(thread_count)
{
int myRank = omp_get_thread_num(); //What thread am I?
dTemp = 1;
// Computing two varibles to buffer through the array which are derivatives from myRank variable
startIndex = myRank * iChunk;
if(iChunkRemainder && (startIndex + iChunk) > iD)
endIndex = iChunkRemainder;
else if (iChunkRemainder && myRank == thread_count - 1 && (startIndex + iChunk) < iD)
endIndex = startIndex + iChunk + iChunkRemainder;
else
endIndex = startIndex + iChunk;
for(int index = startIndex; index < endIndex; index++)
dTemp = dTemp * encryptedMessage[i];
/*if(i < 2)
cout << "Start Index: " << startIndex << " | End Index: " << endIndex << " | Process: " << myRank << " | Result: " << dTemp << endl;*/
decryptedText = decryptedText * dTemp;
}
decryptedText = fmod(decryptedText, iN);
cout << decryptedText << " ";
}
// Store the starting time of the program
double endTime = omp_get_wtime();
cout << "\n\nTotal Runtime: " << endTime - startTime << endl;
return 0;
}