-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRIPEMD-160.cpp
260 lines (201 loc) · 13.4 KB
/
RIPEMD-160.cpp
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
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
#include "RIPEMD-160.h" //Ïîäêëþ÷àåì îïèñàíèå êëàññà
unsigned int RIPEMD_160::F(unsigned int j, unsigned int x, unsigned int y, unsigned int z) //Âûáîð áèòîâîé ôóíêöèè â ñîîòâåòñâèè ñ íîìåðîì öèêëà
{
if (j <= 15)
return x ^ y ^ z;
else if (j <= 31)
return (x & y) | (~x & z);
else if (j <= 47)
return (x | ~y) ^ z;
else if (j <= 63)
return (x & z) | (y & ~z);
else if (j <= 79)
return x ^ (y | ~z);
else
return 0;
}
unsigned int RIPEMD_160::K1(unsigned int j) //Âûáîð êîíñòàíòû â ñîîòâåòñâèè ñ íîìåðîì öèêëà äëÿ ïåðâîãî ïîòîêà
{
if (j <= 15)
return 0x00000000;
else if (j <= 31)
return 0x5A827999;
else if (j <= 47)
return 0x6ED9EBA1;
else if (j <= 63)
return 0x8F1BBCDC;
else if (j <= 79)
return 0xA953FD4E;
else
return 0;
}
unsigned int RIPEMD_160::K2(unsigned int j) //Âûáîð êîíñòàíòû â ñîîòâåòñâèè ñ íîìåðîì öèêëà äëÿ âòîðîãî ïîòîêà
{
if (j <= 15)
return 0x50A28BE6;
else if (j <= 31)
return 0x5C4DD124;
else if (j <= 47)
return 0x6D703EF3;
else if (j <= 63)
return 0x7A6D76E9;
else if (j <= 79)
return 0x00000000;
else
return 0;
}
unsigned int RIPEMD_160::inv(unsigned int value) //Ñìåíà ïîðÿäêà áèò (endians)
{
unsigned int res = 0; //Îáúÿâëÿåì ïåðåìåííóþ ðåçóëüòàòà
res |= ((value >> 0) & 0xFF) << 24; //Ìåíàÿåì
res |= ((value >> 8) & 0xFF) << 16; //Ïîðÿäîê áèò
res |= ((value >> 16) & 0xFF) << 8; //Â êàæäîì èç
res |= ((value >> 24) & 0xFF) << 0; //4õ áàéòîâ
return res; //Âîçâðàùàåì ðåçóëüòàò
}
unsigned int RIPEMD_160::bytes_to_uint(char* bytes) //Ïðåîðàçîâàíèå 4õ áàéòîâ â unsigned int
{
unsigned int res = 0; //Îáúÿâëÿåì ïåðåìåííóþ ðåçóëüòàòà
res |= ((unsigned int)bytes[3] << 24) & 0xFF000000; //Ïðåîáðàçóåì
res |= ((unsigned int)bytes[2] << 16) & 0xFF0000; //Êàæäûé
res |= ((unsigned int)bytes[1] << 8) & 0xFF00; //Èç
res |= ((unsigned int)bytes[0] << 0) & 0xFF; //4õ áàéòîâ
return res; //Âîçâðàùàåì ðåçóëüòàò
}
bool RIPEMD_160::read_file(string fileName) //×òåíèå èç ôàéëà
{
ifstream in(fileName, ios::binary); //Îòêðûâàåì ôàéë â áèíàðíîì ðåæèìå
if (in.fail()) //Âåðíóòü 0
return false; //Åñëè âîçíèêëà îøèáêà
in.seekg(0, ios::end); //Ïîäñ÷åò
unsigned int file_size = (unsigned int)in.tellg(); //Ðàçìåðà
in.seekg(0, ios::beg); //Ôàéëà
if (file_size != 0) {
message.resize(file_size); //Ìåíÿåì ðàçìåð ñòðîêè ðåçóëüòàòà â ñîîòâåòñòâèè ñ ðàçìåðîì ôàéëà
in.read((char*)&message.front(), file_size); //Ñ÷èòûâàåì äàííûå â ìàññèâ
}
in.close(); //Çàêðûâàåì ôàéë
return true; //Âîçâðàùàåì 1 â ñëó÷àå óñïåõà
}
void RIPEMD_160::get_new_mess(string s) {
message.clear();
message.resize(s.size());
message = s;
result.clear();
}
bool RIPEMD_160::write_file(char* fileName, string str) //Çàïèñü â ôàéë
{
ofstream out(fileName); //Îòêðûâàåì èëè ñîçäàåì ôàéë
if (out.fail()) //Âåðíóòü 0
return false; //Åñëè âîçíèêëà îøèáêà
out << str; //Çàïèñûâàåì ñòðîêó ñ ðåçóëüòàòîì â ôàéë
return true; //Âîçâðàùàåì 1 â ñëó÷àå óñïåõà
}
void RIPEMD_160::extension() //Øàã 1 - Ðàñøèðåíèå ñîîáùåíèÿ
{
bitlen = message.size()* 8; //Èñõîäíàÿ äëèíà ñîîáùåíèÿ â áèòàõ (íóæíà äëÿ øàãà 2)
message.push_back((unsigned char)0x80); //Äîáàâëÿåì â êîíåö ñîîáùåíèÿ åäèíè÷íûé áèò
while ((message.size() * 8) % 512 != 448) //Äî òåõ ïîð, ïîêà äëèíà ñîîáùåíèÿ íå ñòàíåò ðàâíîé 448 ïî ìîäóëþ 512,
message.push_back(0); //Çàïîëíÿåì ñîîáùåíèå íóëÿìè
blocks = (unsigned int)(message.size() / 64) + 1; //Êîëè÷åñòâî áëîêîâ äëÿ îáðàáîòêè (+1 íóæíî äëÿ áëîêà èç 8 áàéò, â êîòîðûé äîáàâèòñÿ bitlen)
}
void RIPEMD_160::adding_length() //Øàã 2 - Äîáàâëåíèå äëèíû ñîîáùåíèÿ
{
X = new unsigned int* [blocks]; //Âûäåëÿåì ïàìÿòü ïîä ìàññèâ ìàññèâîâ áëîêîâ
for (unsigned int i = 0; i < blocks; i++) //Ïîêà íå êîí÷èëèñü áëîêè
{
X[i] = new unsigned int[16]; //Âûäåëÿåì ïàìÿòü ïîä òåêóùèé áëîê
for (int j = 0; j < (i == blocks - 1 ? 14 : 16); j++) //Åñëè ýòî íå ïîñëåäíèé áëîê, òî ïåðåíîñèì ïðåîáðàçîâàííîå messgae â X,
X[i][j] = bytes_to_uint(&message[(j * 4) + 64 * i]); //Åñëè áëîê ïîñëåíèé, òî äåëàåì òî æå ñàìîå, íî îñòàâëÿåì 8 áàéò ïîä bitlen
if (i == blocks - 1) //Åñëè ýòî ïîñëåäíèé áëîê
{
X[i][14] = bitlen & 0xFFFFFFFF; //Òî äîáàâëÿåì â íåãî bitlen, ïðè÷åì â âèäå äâóõ 4-áàéòîâûõ ñëîâ,
X[i][15] = bitlen >> 32 & 0xFFFFFFFF; //Ãäå ïåðâûì äîáàâëÿåòñÿ ñëîâî, ñîäåðæàùåå ìëàäøèå ðàçðÿäû.
}
}
}
void RIPEMD_160::initialize_ripemd() //Øàã 3 - Èíèöèàëèçàöèÿ RIPEMD áóôåðà
{
H0 = 0x67452301, H1 = 0xEFCDAB89, H2 = 0x98BADCFE, H3 = 0x10325476, H4 = 0xC3D2E1F0; //Èíèöèàëèçèóåì ðåãèñòðû
}
//Ãëîáàëüíî èíèöèàëèçèóåì âûáîð 32-áèòíûõ ñëîâ èç ñîîáùåíèÿ
unsigned int R1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13 };
unsigned int R2[] = { 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11 };
//Ãëîáàëüíî èíèöèàëèçèóåì íàáîð äëÿ áèòîâîãî ñäâèãà
unsigned int S1[] = { 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6 };
unsigned int S2[] = { 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 };
void RIPEMD_160::message_processing() //Øàã 4 - Îáðàáîòêà ñîîáùåíèÿ â áëîêàõ
{
for (unsigned int i = 0; i < blocks; i++) //Öèêë áëîêîâ ñîîáùåíèÿ
{
A1 = H0, B1 = H1, C1 = H2, D1 = H3, E1 = H4; //Ñîõðàíÿåì çíà÷åíèÿ çíà÷åíèÿ ðåãèñòðîâ íà êàæäîì ýòàïå öèêëà
A2 = H0, B2 = H1, C2 = H2, D2 = H3, E2 = H4; //Äëÿ äâóõ ïîòîêîâ
//Ìàãèÿ
for (unsigned int j = 0; j < 80; j++)
{
T = ROTATE_LEFT((A1 + F(j, B1, C1, D1) + X[i][R1[j]] + K1(j)), S1[j]) + E1;
A1 = E1, E1 = D1, D1 = ROTATE_LEFT(C1, 10), C1 = B1, B1 = T;
T = ROTATE_LEFT((A2 + F(79 - j, B2, C2, D2) + X[i][R2[j]] + K2(j)), S2[j]) + E2;
A2 = E2, E2 = D2, D2 = ROTATE_LEFT(C2, 10), C2 = B2, B2 = T;
}
//Êîíåö ìàãèè
T = H1 + C1 + D2; //Îáíîâëÿåì çíà÷åíèÿ ðåãèñòðîâ
H1 = H2 + D1 + E2, H2 = H3 + E1 + A2, H3 = H4 + A1 + B2, H4 = H0 + B1 + C2; //Íà êàæäîì ýòàïå öèêëà
H0 = T; //Äëÿ äâóõ ïîòîêîâ
}
for (unsigned int i = 0; i < blocks; i++) //Ïîêà íå êîí÷èëèñü áëîêè
delete[] X[i]; //Îñâîáîæäàåì ïàìÿòü, âûäåëåííóþ ïîä òåêóùèé áëîê
delete[] X; //Îñâîáîæäàåì ïàìÿòü, âûäåëåííóþ ïîä âåñü ìàññèâ ìàññèâîâ áëîêîâ
}
string RIPEMD_160::ripemd_160() //Àëãîðèòì ïðåîáðàçîâàíèÿ
{
extension(); //Øàã 1 - Ðàñøèðåíèå ñîîáùåíèÿ
adding_length(); //Øàã 2 - Äîáàâëåíèå äëèíû ñîîáùåíèÿ
initialize_ripemd(); //Øàã 3 - Èíèöèàëèçàöèÿ RIPEMD áóôåðà
message_processing(); //Øàã 4 - Îáðàáîòêà ñîîáùåíèÿ â áëîêàõ
result << hex << inv(H0) << inv(H1) << inv(H2) << inv(H3) << inv(H4); //Øàã 5 - Ðåçóëüòàò â âèäå õýø-ñîîáùåíèÿ
return result.str(); //Âîçâðàùàåì ðåçóëüòàò â âèäå õýø-ñîîáùåíèÿ
}
//--------------------------------------------------------------------------------------------------------------------
string RIPEMD_160::random_string()
{
auto randchar = []() -> char
{
const char charset[] =
"0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
const size_t max_index = (sizeof(charset) - 1);
return charset[rand() % max_index];
};
string str;
for (int i = 0; i < 15; i++) {
str.push_back(randchar());
}
return str;
}
string RIPEMD_160::ripemd_160_exp(int flag) //Àëãîðèòì ïðåîáðàçîâàíèÿ
{
extension(); //Øàã 1 - Ðàñøèðåíèå ñîîáùåíèÿ
adding_length(); //Øàã 2 - Äîáàâëåíèå äëèíû ñîîáùåíèÿ
initialize_ripemd(); //Øàã 3 - Èíèöèàëèçàöèÿ RIPEMD áóôåðà
message_processing(); //Øàã 4 - Îáðàáîòêà ñîîáùåíèÿ â áëîêàõ
result << hex << inv(H0) << inv(H1) << inv(H2) << inv(H3) << inv(H4); //Øàã 5 - Ðåçóëüòàò â âèäå õýø-ñîîáùåíèÿ
return result.str(); //Âîçâðàùàåì ðåçóëüòàò â âèäå õýø-ñîîáùåíèÿ
}