-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathRIPEMD160.java
301 lines (266 loc) · 9.38 KB
/
RIPEMD160.java
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
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
//package ecc;
/**
* (c) Mads Johan Jurik
* used with permission
*/
public class RIPEMD160 {
private static final int[][] ArgArray =
{{ 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},
{ 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}};
private static final int[][] IndexArray =
{{ 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},
{ 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}};
private int[] MDbuf;
public RIPEMD160 () {
MDbuf = new int[5];
MDbuf[0] = 0x67452301;
MDbuf[1] = 0xefcdab89;
MDbuf[2] = 0x98badcfe;
MDbuf[3] = 0x10325476;
MDbuf[4] = 0xc3d2e1f0;
working = new int[16];
working_ptr = 0;
msglen = 0;
}
public void reset () {
MDbuf = new int[5];
MDbuf[0] = 0x67452301;
MDbuf[1] = 0xefcdab89;
MDbuf[2] = 0x98badcfe;
MDbuf[3] = 0x10325476;
MDbuf[4] = 0xc3d2e1f0;
working = new int[16];
working_ptr = 0;
msglen = 0;
}
private void compress (int[] X) {
int index = 0;
int a, b, c, d, e;
int A, B, C, D, E;
int temp, s;
A = a = MDbuf[0];
B = b = MDbuf[1];
C = c = MDbuf[2];
D = d = MDbuf[3];
E = e = MDbuf[4];
for (; index < 16; index++) {
// The 16 FF functions - round 1 */
temp = a + (b ^ c ^ d) + X[IndexArray[0][index]];
a = e;
e = d;
d = (c << 10) | (c >>> 22);
c = b;
s = ArgArray[0][index];
b = ((temp << s) | (temp >>> (32 - s))) + a;
// The 16 JJJ functions - parallel round 1 */
temp = A + (B ^ (C | ~D)) + X[IndexArray[1][index]] + 0x50a28be6;
A = E;
E = D;
D = (C << 10) | (C >>> 22);
C = B;
s = ArgArray[1][index];
B = ((temp << s) | (temp >>> (32 - s))) + A;
}
for (; index < 32; index++) {
// The 16 GG functions - round 2 */
temp = a + ((b & c) | (~b & d)) + X[IndexArray[0][index]] + 0x5a827999;
a = e;
e = d;
d = (c << 10) | (c >>> 22);
c = b;
s = ArgArray[0][index];
b = ((temp << s) | (temp >>> (32 - s))) + a;
// The 16 III functions - parallel round 2 */
temp = A + ((B & D) | (C & ~D)) + X[IndexArray[1][index]] + 0x5c4dd124;
A = E;
E = D;
D = (C << 10) | (C >>> 22);
C = B;
s = ArgArray[1][index];
B = ((temp << s) | (temp >>> (32 - s))) + A;
}
for (; index < 48; index++) {
// The 16 HH functions - round 3 */
temp = a + ((b | ~c) ^ d) + X[IndexArray[0][index]] + 0x6ed9eba1;
a = e;
e = d;
d = (c << 10) | (c >>> 22);
c = b;
s = ArgArray[0][index];
b = ((temp << s) | (temp >>> (32 - s))) + a;
// The 16 HHH functions - parallel round 3 */
temp = A + ((B | ~C) ^ D) + X[IndexArray[1][index]] + 0x6d703ef3;
A = E;
E = D;
D = (C << 10) | (C >>> 22);
C = B;
s = ArgArray[1][index];
B = ((temp << s) | (temp >>> (32 - s))) + A;
}
for (; index < 64; index++) {
// The 16 II functions - round 4 */
temp = a + ((b & d) | (c & ~d)) + X[IndexArray[0][index]] + 0x8f1bbcdc;
a = e;
e = d;
d = (c << 10) | (c >>> 22);
c = b;
s = ArgArray[0][index];
b = ((temp << s) | (temp >>> (32 - s))) + a;
// The 16 GGG functions - parallel round 4 */
temp = A + ((B & C) | (~B & D)) + X[IndexArray[1][index]] + 0x7a6d76e9;
A = E;
E = D;
D = (C << 10) | (C >>> 22);
C = B;
s = ArgArray[1][index];
B = ((temp << s) | (temp >>> (32 - s))) + A;
}
for (; index < 80; index++) {
// The 16 JJ functions - round 5 */
temp = a + (b ^ (c | ~d)) + X[IndexArray[0][index]] + 0xa953fd4e;
a = e;
e = d;
d = (c << 10) | (c >>> 22);
c = b;
s = ArgArray[0][index];
b = ((temp << s) | (temp >>> (32 - s))) + a;
// The 16 FFF functions - parallel round 5 */
temp = A + (B ^ C ^ D) + X[IndexArray[1][index]];
A = E;
E = D;
D = (C << 10) | (C >>> 22);
C = B;
s = ArgArray[1][index];
B = ((temp << s) | (temp >>> (32 - s))) + A;
}
/* combine results */
D += c + MDbuf[1]; /* final result for MDbuf[0] */
MDbuf[1] = MDbuf[2] + d + E;
MDbuf[2] = MDbuf[3] + e + A;
MDbuf[3] = MDbuf[4] + a + B;
MDbuf[4] = MDbuf[0] + b + C;
MDbuf[0] = D;
}
private void MDfinish (int[] array, int lswlen, int mswlen) {
int[] X = array; /* message words */
/* append the bit m_n == 1 */
X[(lswlen>>2)&15] ^= 1 << (((lswlen&3) << 3) + 7);
if ((lswlen & 63) > 55) {
/* length goes to next block */
compress (X);
for (int i = 0; i < 14; i++) X[i] = 0;
}
/* append length in bits*/
X[14] = lswlen << 3;
X[15] = (lswlen >> 29) | (mswlen << 3);
compress (X);
}
private int[] working;
private int working_ptr;
private int msglen;
public void update (byte input) {
working[working_ptr>>2] ^= ((int) input) << ((working_ptr&3) << 3);
working_ptr++;
if (working_ptr == 64) {
compress (working);
for (int j = 0; j < 16; j++) working[j] = 0;
working_ptr = 0;
}
msglen++;
}
public void update (byte[] input) {
for (int i = 0; i < input.length; i++) {
working[working_ptr>>2] ^= ((int) input[i]) << ((working_ptr&3) << 3);
working_ptr++;
if (working_ptr == 64) {
compress (working);
for (int j = 0; j < 16; j++) working[j] = 0;
working_ptr = 0;
}
}
msglen += input.length;
}
public void update (byte[] input, int offset, int len) {
if (offset+len >= input.length) {
for (int i = offset; i < input.length; i++) {
working[working_ptr>>2] ^= ((int) input[i]) << ((working_ptr&3) << 3);
working_ptr++;
if (working_ptr == 64) {
compress (working);
for (int j = 0; j < 16; j++) working[j] = 0;
working_ptr = 0;
}
}
msglen += input.length - offset;
} else {
for (int i = offset; i < offset+len; i++) {
working[working_ptr>>2] ^= ((int) input[i]) << ((working_ptr&3) << 3);
working_ptr++;
if (working_ptr == 64) {
compress (working);
for (int j = 0; j < 16; j++) working[j] = 0;
working_ptr = 0;
}
}
msglen += len;
}
}
public void update (String s) {
byte[] bytearray = new byte[s.length ()];
for (int i = 0; i < bytearray.length; i++) {
bytearray[i] = (byte) s.charAt (i);
}
update (bytearray);
}
public byte[] digest () {
MDfinish (working, msglen, 0);
byte[] res = new byte[20];
for (int i = 0; i < 20; i++)
res[i] = (byte) ((MDbuf[i>>2] >>> ((i & 3) << 3)) & 0x000000FF);
return res;
}
public byte[] digest (byte[] input) {
update (input);
return digest ();
}
public byte[] digest (byte[] input, int offset, int len) {
update (input, offset, len);
return digest ();
}
public int[] intdigest () {
int[] res = new int[5];
for (int i = 0; i < 5; i++) res[i] = MDbuf[i];
return res;
}
}
/*
Text RIPEMD160 RIPEMD128
"" 9c1185a5c5e9fc54612808977ee8f548b2258d31 cdf26213a150dc3ecb610f18f6b38b46
"a" 0bdc9d2d256b3ee9daae347be6f4dc835a467ffe 86be7afa339d0fc7cfc785e72f578d33
"abc" 8eb208f7e05d987a9b044a8e98c6b087f15a0bfc c14a12199c66e4ba84636b0f69144c77
"message digest" 5d0689ef49d2fae572b881b123a85ffa21595f36 9e327b3d6e523062afc1132d7df9d1b8
1) f71c27109c692c1b56bbdceb5b9d2865b3708dbc fd2aa607f71dc8f510714922b371834e
2) 12a053384a9c0c88e405a06c27dcf49ada62eb2b a1aa0689d0fafa2ddc22e88b49133a06
3) b0e20b6e3116640286ed3a87a5713079b21f5189 d1e959eb179c911faea4624c60c5c702
8 x "1234567890" 9b752e45573d4b39f4dbd3323cab82bf63326bfb 3f45ef194732c2dbb2c4a2c769795fa3
1 mio. x "a" 52783243c1697bdbe16d37f97f68f08325dc1528 4a7f5723f954eba1216c9d8f6320431f
1) "abcdefghijklmnopqrstuvwxyz"
2) "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
3) "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
*/