-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrsaengine.cpp
More file actions
145 lines (101 loc) · 4.4 KB
/
Copy pathrsaengine.cpp
File metadata and controls
145 lines (101 loc) · 4.4 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
#include "rsaengine.h"
#include <chrono>
#include <cmath>
int RSAEngine::engineCount = 0;
RSAEngine::RSAEngine(RSAKey* key) {
currentKey = key;
lastEncryptTime = 0;
lastDecryptTime = 0;
benchmarkResults = nullptr;
benchmarkCount = 0;
engineCount++;
}
BigInt RSAEngine::encrypt(const BigInt& mesaj) {
auto start = chrono::high_resolution_clock::now();
BigInt result = mesaj.modpow(RSAKey::getE(), currentKey->getN()); //mesaj ^ e % n
auto end = chrono::high_resolution_clock::now();
lastEncryptTime = chrono::duration_cast<chrono::microseconds>(end - start).count();
return result;
}
BigInt RSAEngine::decrypt(const BigInt& criptat) {
auto start = chrono::high_resolution_clock::now();
BigInt result = criptat.modpow(currentKey->getD(), currentKey->getN()); //mesaj(acum criptat) ^ d % n
auto end = chrono::high_resolution_clock::now();
lastDecryptTime = chrono::duration_cast<chrono::microseconds>(end - start).count();
return result;
}
inline double RSAEngine::getLastEncryptTime() const {
return this->lastEncryptTime;
}
inline double RSAEngine::getLastDecryptTime() const {
return this->lastDecryptTime;
}
RSAEngine::RSAEngine(const RSAEngine& other) {
currentKey = other.currentKey;
lastEncryptTime = other.lastEncryptTime;
lastDecryptTime = other.lastDecryptTime;
benchmarkCount = other.benchmarkCount;
if (benchmarkCount > 0) {
benchmarkResults = new float[benchmarkCount];
memcpy(benchmarkResults, other.benchmarkResults, benchmarkCount * sizeof(float));
} else {
benchmarkResults = nullptr;
}
engineCount++;
}
RSAEngine& RSAEngine::operator=(const RSAEngine& other) {
if (this == &other)
return *this;
currentKey = other.currentKey;
lastEncryptTime = other.lastEncryptTime;
lastDecryptTime = other.lastDecryptTime;
benchmarkCount = other.benchmarkCount;
delete[] benchmarkResults; // eliberez mem, adica ce era inainte pe *this inainte sa aloc
if (benchmarkCount > 0) {
benchmarkResults = new float[benchmarkCount]; // aici si aloc
memcpy(benchmarkResults, other.benchmarkResults, benchmarkCount * sizeof(float));
} else {
benchmarkResults = nullptr;
}
return *this;
}
void RSAEngine::benchmark(int iteratii) {
if (benchmarkResults) delete[] benchmarkResults; //sterg rez vechi
benchmarkCount = iteratii;
benchmarkResults = new float[iteratii];
BigInt testMsg(42); //am ales un numar random pe care sa-l testez, pot sa pun orice vreau, 99, 67 etc
for (int i = 0; i < iteratii; i++) {
auto start = chrono::high_resolution_clock::now();
volatile BigInt result = testMsg.modpow(RSAKey::getE(), currentKey->getN());
//asta nu a fost acoperita la lab si ar fi bine sa o mentionez
//cand rulam teste pentru cod de asamblare, aveam probleme cu g++ care imi eficientiza codul cand voiam sa rulez benchmark uri, fapt care nu se observa decat in objdump uri
//atunci, pe langa alte lucruri am folosit keyword ul volatile care previne compilatorul sa faca optimizari, forteaza sa faca calculul
auto end = chrono::high_resolution_clock::now();
benchmarkResults[i] = chrono::duration_cast<chrono::microseconds>(end - start).count();
}
}
ostream& operator<<(ostream& os, const RSAEngine& eng){
os<< "Total engines created: " << eng.engineCount<<endl;
os<< "Last encrypt time: " << eng.getLastEncryptTime() <<endl;
os << "Last decrypt time: " << eng.getLastDecryptTime() << endl;
if (eng.benchmarkCount > 0) //adica daca s a dat vreun benchmark pana acum
{
os<< "Benchmark results: ( " << eng.benchmarkCount << " runs ): " << endl;
float total = 0;
for (int i = 0 ; i< eng.benchmarkCount; i++)
total += log(eng.benchmarkResults[i]);
os << "The geometric mean of the benchmark results is : " << fixed << setprecision(2) <<exp(total / eng.benchmarkCount )<< endl;
}
return os;
}
istream& operator>>(istream& is, RSAEngine& eng){ // din nou, tipul de retur e referinta ptr ca streamurile nu se pot copia ( nu au copy constr )
int iteratii;
cout<<"How many times should the benchmark be ran?: ";
is>> iteratii;
eng.benchmark(iteratii);
cout<< eng;
return is;
}
RSAEngine::~RSAEngine() {
if (benchmarkResults) delete[] benchmarkResults;
}