]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_ripemd160.cpp
87ca21ada432de785abe17a3413db684f94ad061
[user/henk/code/inspircd.git] / src / modules / m_ripemd160.cpp
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  InspIRCd: (C) 2002-2009 InspIRCd Development Team
6  * See: http://wiki.inspircd.org/Credits
7  *
8  * This program is free but copyrighted software; see
9  *            the file COPYING for details.
10  *
11  * ---------------------------------------------------
12  */
13
14 /*
15  *
16  *      AUTHOR:   Antoon Bosselaers, ESAT-COSIC
17  *      DATE:     1 March 1996
18  *      VERSION:  1.0
19  *
20  *      Copyright (c) Katholieke Universiteit Leuven
21  *      1996, All Rights Reserved
22  *
23  *  Conditions for use of the RIPEMD-160 Software
24  *
25  *  The RIPEMD-160 software is freely available for use under the terms and
26  *  conditions described hereunder, which shall be deemed to be accepted by
27  *  any user of the software and applicable on any use of the software:
28  *
29  *  1. K.U.Leuven Department of Electrical Engineering-ESAT/COSIC shall for
30  *     all purposes be considered the owner of the RIPEMD-160 software and of
31  *     all copyright, trade secret, patent or other intellectual property
32  *     rights therein.
33  *  2. The RIPEMD-160 software is provided on an "as is" basis without
34  *     warranty of any sort, express or implied. K.U.Leuven makes no
35  *     representation that the use of the software will not infringe any
36  *     patent or proprietary right of third parties. User will indemnify
37  *     K.U.Leuven and hold K.U.Leuven harmless from any claims or liabilities
38  *     which may arise as a result of its use of the software. In no
39  *     circumstances K.U.Leuven R&D will be held liable for any deficiency,
40  *     fault or other mishappening with regard to the use or performance of
41  *     the software.
42  *  3. User agrees to give due credit to K.U.Leuven in scientific publications
43  *     or communications in relation with the use of the RIPEMD-160 software
44  *     as follows: RIPEMD-160 software written by Antoon Bosselaers,
45  *     available at http://www.esat.kuleuven.be/~cosicart/ps/AB-9601/.
46  *
47  */
48
49
50 /* $ModDesc: Allows for RIPEMD-160 encrypted oper passwords */
51 /* $ModDep: m_hash.h */
52
53 /* macro definitions */
54
55 #include "inspircd.h"
56 #ifdef HAS_STDINT
57 #include <stdint.h>
58 #endif
59 #include "m_hash.h"
60
61 #define RMDsize 160
62
63 #ifndef HAS_STDINT
64 typedef         unsigned char           byte;
65 typedef         unsigned int            dword;
66 #else
67 typedef         uint8_t                 byte;
68 typedef         uint32_t                dword;
69 #endif
70
71 /* collect four bytes into one word: */
72 #define BYTES_TO_DWORD(strptr)                    \
73             (((dword) *((strptr)+3) << 24) | \
74              ((dword) *((strptr)+2) << 16) | \
75              ((dword) *((strptr)+1) <<  8) | \
76              ((dword) *(strptr)))
77
78 /* ROL(x, n) cyclically rotates x over n bits to the left */
79 /* x must be of an unsigned 32 bits type and 0 <= n < 32. */
80 #define ROL(x, n)        (((x) << (n)) | ((x) >> (32-(n))))
81
82 /* the five basic functions F(), G() and H() */
83 #define F(x, y, z)        ((x) ^ (y) ^ (z))
84 #define G(x, y, z)        (((x) & (y)) | (~(x) & (z)))
85 #define H(x, y, z)        (((x) | ~(y)) ^ (z))
86 #define I(x, y, z)        (((x) & (z)) | ((y) & ~(z)))
87 #define J(x, y, z)        ((x) ^ ((y) | ~(z)))
88
89 /* the ten basic operations FF() through III() */
90
91 #define FF(a, b, c, d, e, x, s)        {\
92       (a) += F((b), (c), (d)) + (x);\
93       (a) = ROL((a), (s)) + (e);\
94       (c) = ROL((c), 10);\
95    }
96
97 #define GG(a, b, c, d, e, x, s)        {\
98       (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
99       (a) = ROL((a), (s)) + (e);\
100       (c) = ROL((c), 10);\
101    }
102
103 #define HH(a, b, c, d, e, x, s)        {\
104       (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
105       (a) = ROL((a), (s)) + (e);\
106       (c) = ROL((c), 10);\
107    }
108
109 #define II(a, b, c, d, e, x, s)        {\
110       (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
111       (a) = ROL((a), (s)) + (e);\
112       (c) = ROL((c), 10);\
113    }
114
115 #define JJ(a, b, c, d, e, x, s)        {\
116       (a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\
117       (a) = ROL((a), (s)) + (e);\
118       (c) = ROL((c), 10);\
119    }
120
121 #define FFF(a, b, c, d, e, x, s)        {\
122       (a) += F((b), (c), (d)) + (x);\
123       (a) = ROL((a), (s)) + (e);\
124       (c) = ROL((c), 10);\
125    }
126
127 #define GGG(a, b, c, d, e, x, s)        {\
128       (a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\
129       (a) = ROL((a), (s)) + (e);\
130       (c) = ROL((c), 10);\
131    }
132
133 #define HHH(a, b, c, d, e, x, s)        {\
134       (a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\
135       (a) = ROL((a), (s)) + (e);\
136       (c) = ROL((c), 10);\
137    }
138
139 #define III(a, b, c, d, e, x, s)        {\
140       (a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\
141       (a) = ROL((a), (s)) + (e);\
142       (c) = ROL((c), 10);\
143    }
144
145 #define JJJ(a, b, c, d, e, x, s)        {\
146       (a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\
147       (a) = ROL((a), (s)) + (e);\
148       (c) = ROL((c), 10);\
149    }
150
151
152 class ModuleRIPEMD160 : public Module
153 {
154
155         void MDinit(dword *MDbuf, unsigned int* key)
156         {
157                 if (key)
158                 {
159                         ServerInstance->Logs->Log("m_ripemd160.so", DEBUG, "initialize with custom mdbuf");
160                         MDbuf[0] = key[0];
161                         MDbuf[1] = key[1];
162                         MDbuf[2] = key[2];
163                         MDbuf[3] = key[3];
164                         MDbuf[4] = key[4];
165                 }
166                 else
167                 {
168                         ServerInstance->Logs->Log("m_ripemd160.so", DEBUG, "initialize with default mdbuf");
169                         MDbuf[0] = 0x67452301UL;
170                         MDbuf[1] = 0xefcdab89UL;
171                         MDbuf[2] = 0x98badcfeUL;
172                         MDbuf[3] = 0x10325476UL;
173                         MDbuf[4] = 0xc3d2e1f0UL;
174                 }
175                 return;
176         }
177
178
179         void compress(dword *MDbuf, dword *X)
180         {
181                 dword aa = MDbuf[0],  bb = MDbuf[1],  cc = MDbuf[2],
182                         dd = MDbuf[3],  ee = MDbuf[4];
183                 dword aaa = MDbuf[0], bbb = MDbuf[1], ccc = MDbuf[2],
184                         ddd = MDbuf[3], eee = MDbuf[4];
185
186                 /* round 1 */
187                 FF(aa, bb, cc, dd, ee, X[ 0], 11);
188                 FF(ee, aa, bb, cc, dd, X[ 1], 14);
189                 FF(dd, ee, aa, bb, cc, X[ 2], 15);
190                 FF(cc, dd, ee, aa, bb, X[ 3], 12);
191                 FF(bb, cc, dd, ee, aa, X[ 4],  5);
192                 FF(aa, bb, cc, dd, ee, X[ 5],  8);
193                 FF(ee, aa, bb, cc, dd, X[ 6],  7);
194                 FF(dd, ee, aa, bb, cc, X[ 7],  9);
195                 FF(cc, dd, ee, aa, bb, X[ 8], 11);
196                 FF(bb, cc, dd, ee, aa, X[ 9], 13);
197                 FF(aa, bb, cc, dd, ee, X[10], 14);
198                 FF(ee, aa, bb, cc, dd, X[11], 15);
199                 FF(dd, ee, aa, bb, cc, X[12],  6);
200                 FF(cc, dd, ee, aa, bb, X[13],  7);
201                 FF(bb, cc, dd, ee, aa, X[14],  9);
202                 FF(aa, bb, cc, dd, ee, X[15],  8);
203
204                 /* round 2 */
205                 GG(ee, aa, bb, cc, dd, X[ 7],  7);
206                 GG(dd, ee, aa, bb, cc, X[ 4],  6);
207                 GG(cc, dd, ee, aa, bb, X[13],  8);
208                 GG(bb, cc, dd, ee, aa, X[ 1], 13);
209                 GG(aa, bb, cc, dd, ee, X[10], 11);
210                 GG(ee, aa, bb, cc, dd, X[ 6],  9);
211                 GG(dd, ee, aa, bb, cc, X[15],  7);
212                 GG(cc, dd, ee, aa, bb, X[ 3], 15);
213                 GG(bb, cc, dd, ee, aa, X[12],  7);
214                 GG(aa, bb, cc, dd, ee, X[ 0], 12);
215                 GG(ee, aa, bb, cc, dd, X[ 9], 15);
216                 GG(dd, ee, aa, bb, cc, X[ 5],  9);
217                 GG(cc, dd, ee, aa, bb, X[ 2], 11);
218                 GG(bb, cc, dd, ee, aa, X[14],  7);
219                 GG(aa, bb, cc, dd, ee, X[11], 13);
220                 GG(ee, aa, bb, cc, dd, X[ 8], 12);
221
222                 /* round 3 */
223                 HH(dd, ee, aa, bb, cc, X[ 3], 11);
224                 HH(cc, dd, ee, aa, bb, X[10], 13);
225                 HH(bb, cc, dd, ee, aa, X[14],  6);
226                 HH(aa, bb, cc, dd, ee, X[ 4],  7);
227                 HH(ee, aa, bb, cc, dd, X[ 9], 14);
228                 HH(dd, ee, aa, bb, cc, X[15],  9);
229                 HH(cc, dd, ee, aa, bb, X[ 8], 13);
230                 HH(bb, cc, dd, ee, aa, X[ 1], 15);
231                 HH(aa, bb, cc, dd, ee, X[ 2], 14);
232                 HH(ee, aa, bb, cc, dd, X[ 7],  8);
233                 HH(dd, ee, aa, bb, cc, X[ 0], 13);
234                 HH(cc, dd, ee, aa, bb, X[ 6],  6);
235                 HH(bb, cc, dd, ee, aa, X[13],  5);
236                 HH(aa, bb, cc, dd, ee, X[11], 12);
237                 HH(ee, aa, bb, cc, dd, X[ 5],  7);
238                 HH(dd, ee, aa, bb, cc, X[12],  5);
239
240                 /* round 4 */
241                 II(cc, dd, ee, aa, bb, X[ 1], 11);
242                 II(bb, cc, dd, ee, aa, X[ 9], 12);
243                 II(aa, bb, cc, dd, ee, X[11], 14);
244                 II(ee, aa, bb, cc, dd, X[10], 15);
245                 II(dd, ee, aa, bb, cc, X[ 0], 14);
246                 II(cc, dd, ee, aa, bb, X[ 8], 15);
247                 II(bb, cc, dd, ee, aa, X[12],  9);
248                 II(aa, bb, cc, dd, ee, X[ 4],  8);
249                 II(ee, aa, bb, cc, dd, X[13],  9);
250                 II(dd, ee, aa, bb, cc, X[ 3], 14);
251                 II(cc, dd, ee, aa, bb, X[ 7],  5);
252                 II(bb, cc, dd, ee, aa, X[15],  6);
253                 II(aa, bb, cc, dd, ee, X[14],  8);
254                 II(ee, aa, bb, cc, dd, X[ 5],  6);
255                 II(dd, ee, aa, bb, cc, X[ 6],  5);
256                 II(cc, dd, ee, aa, bb, X[ 2], 12);
257
258                 /* round 5 */
259                 JJ(bb, cc, dd, ee, aa, X[ 4],  9);
260                 JJ(aa, bb, cc, dd, ee, X[ 0], 15);
261                 JJ(ee, aa, bb, cc, dd, X[ 5],  5);
262                 JJ(dd, ee, aa, bb, cc, X[ 9], 11);
263                 JJ(cc, dd, ee, aa, bb, X[ 7],  6);
264                 JJ(bb, cc, dd, ee, aa, X[12],  8);
265                 JJ(aa, bb, cc, dd, ee, X[ 2], 13);
266                 JJ(ee, aa, bb, cc, dd, X[10], 12);
267                 JJ(dd, ee, aa, bb, cc, X[14],  5);
268                 JJ(cc, dd, ee, aa, bb, X[ 1], 12);
269                 JJ(bb, cc, dd, ee, aa, X[ 3], 13);
270                 JJ(aa, bb, cc, dd, ee, X[ 8], 14);
271                 JJ(ee, aa, bb, cc, dd, X[11], 11);
272                 JJ(dd, ee, aa, bb, cc, X[ 6],  8);
273                 JJ(cc, dd, ee, aa, bb, X[15],  5);
274                 JJ(bb, cc, dd, ee, aa, X[13],  6);
275
276                 /* parallel round 1 */
277                 JJJ(aaa, bbb, ccc, ddd, eee, X[ 5],  8);
278                 JJJ(eee, aaa, bbb, ccc, ddd, X[14],  9);
279                 JJJ(ddd, eee, aaa, bbb, ccc, X[ 7],  9);
280                 JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11);
281                 JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13);
282                 JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15);
283                 JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15);
284                 JJJ(ddd, eee, aaa, bbb, ccc, X[ 4],  5);
285                 JJJ(ccc, ddd, eee, aaa, bbb, X[13],  7);
286                 JJJ(bbb, ccc, ddd, eee, aaa, X[ 6],  7);
287                 JJJ(aaa, bbb, ccc, ddd, eee, X[15],  8);
288                 JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11);
289                 JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14);
290                 JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14);
291                 JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12);
292                 JJJ(aaa, bbb, ccc, ddd, eee, X[12],  6);
293
294                 /* parallel round 2 */
295                 III(eee, aaa, bbb, ccc, ddd, X[ 6],  9);
296                 III(ddd, eee, aaa, bbb, ccc, X[11], 13);
297                 III(ccc, ddd, eee, aaa, bbb, X[ 3], 15);
298                 III(bbb, ccc, ddd, eee, aaa, X[ 7],  7);
299                 III(aaa, bbb, ccc, ddd, eee, X[ 0], 12);
300                 III(eee, aaa, bbb, ccc, ddd, X[13],  8);
301                 III(ddd, eee, aaa, bbb, ccc, X[ 5],  9);
302                 III(ccc, ddd, eee, aaa, bbb, X[10], 11);
303                 III(bbb, ccc, ddd, eee, aaa, X[14],  7);
304                 III(aaa, bbb, ccc, ddd, eee, X[15],  7);
305                 III(eee, aaa, bbb, ccc, ddd, X[ 8], 12);
306                 III(ddd, eee, aaa, bbb, ccc, X[12],  7);
307                 III(ccc, ddd, eee, aaa, bbb, X[ 4],  6);
308                 III(bbb, ccc, ddd, eee, aaa, X[ 9], 15);
309                 III(aaa, bbb, ccc, ddd, eee, X[ 1], 13);
310                 III(eee, aaa, bbb, ccc, ddd, X[ 2], 11);
311
312                 /* parallel round 3 */
313                 HHH(ddd, eee, aaa, bbb, ccc, X[15],  9);
314                 HHH(ccc, ddd, eee, aaa, bbb, X[ 5],  7);
315                 HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15);
316                 HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11);
317                 HHH(eee, aaa, bbb, ccc, ddd, X[ 7],  8);
318                 HHH(ddd, eee, aaa, bbb, ccc, X[14],  6);
319                 HHH(ccc, ddd, eee, aaa, bbb, X[ 6],  6);
320                 HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14);
321                 HHH(aaa, bbb, ccc, ddd, eee, X[11], 12);
322                 HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13);
323                 HHH(ddd, eee, aaa, bbb, ccc, X[12],  5);
324                 HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14);
325                 HHH(bbb, ccc, ddd, eee, aaa, X[10], 13);
326                 HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13);
327                 HHH(eee, aaa, bbb, ccc, ddd, X[ 4],  7);
328                 HHH(ddd, eee, aaa, bbb, ccc, X[13],  5);
329
330                 /* parallel round 4 */
331                 GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15);
332                 GGG(bbb, ccc, ddd, eee, aaa, X[ 6],  5);
333                 GGG(aaa, bbb, ccc, ddd, eee, X[ 4],  8);
334                 GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11);
335                 GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14);
336                 GGG(ccc, ddd, eee, aaa, bbb, X[11], 14);
337                 GGG(bbb, ccc, ddd, eee, aaa, X[15],  6);
338                 GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14);
339                 GGG(eee, aaa, bbb, ccc, ddd, X[ 5],  6);
340                 GGG(ddd, eee, aaa, bbb, ccc, X[12],  9);
341                 GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12);
342                 GGG(bbb, ccc, ddd, eee, aaa, X[13],  9);
343                 GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12);
344                 GGG(eee, aaa, bbb, ccc, ddd, X[ 7],  5);
345                 GGG(ddd, eee, aaa, bbb, ccc, X[10], 15);
346                 GGG(ccc, ddd, eee, aaa, bbb, X[14],  8);
347
348                 /* parallel round 5 */
349                 FFF(bbb, ccc, ddd, eee, aaa, X[12] ,  8);
350                 FFF(aaa, bbb, ccc, ddd, eee, X[15] ,  5);
351                 FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12);
352                 FFF(ddd, eee, aaa, bbb, ccc, X[ 4] ,  9);
353                 FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12);
354                 FFF(bbb, ccc, ddd, eee, aaa, X[ 5] ,  5);
355                 FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14);
356                 FFF(eee, aaa, bbb, ccc, ddd, X[ 7] ,  6);
357                 FFF(ddd, eee, aaa, bbb, ccc, X[ 6] ,  8);
358                 FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13);
359                 FFF(bbb, ccc, ddd, eee, aaa, X[13] ,  6);
360                 FFF(aaa, bbb, ccc, ddd, eee, X[14] ,  5);
361                 FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15);
362                 FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13);
363                 FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11);
364                 FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11);
365
366                 /* combine results */
367                 ddd += cc + MDbuf[1];               /* final result for MDbuf[0] */
368                 MDbuf[1] = MDbuf[2] + dd + eee;
369                 MDbuf[2] = MDbuf[3] + ee + aaa;
370                 MDbuf[3] = MDbuf[4] + aa + bbb;
371                 MDbuf[4] = MDbuf[0] + bb + ccc;
372                 MDbuf[0] = ddd;
373
374                 return;
375         }
376
377         void MDfinish(dword *MDbuf, byte *strptr, dword lswlen, dword mswlen)
378         {
379                 unsigned int i;                                 /* counter       */
380                 dword        X[16];                             /* message words */
381
382                 memset(X, 0, sizeof(X));
383
384                 /* put bytes from strptr into X */
385                 for (i=0; i<(lswlen&63); i++) {
386                         /* byte i goes into word X[i div 4] at pos.  8*(i mod 4)  */
387                         X[i>>2] ^= (dword) *strptr++ << (8 * (i&3));
388                 }
389
390                 /* append the bit m_n == 1 */
391                 X[(lswlen>>2)&15] ^= (dword)1 << (8*(lswlen&3) + 7);
392
393                 if ((lswlen & 63) > 55) {
394                         /* length goes to next block */
395                         compress(MDbuf, X);
396                         memset(X, 0, sizeof(X));
397                 }
398
399                 /* append length in bits*/
400                 X[14] = lswlen << 3;
401                 X[15] = (lswlen >> 29) | (mswlen << 3);
402                 compress(MDbuf, X);
403
404                 return;
405         }
406
407         byte *RMD(byte *message, dword length, unsigned int* key)
408         {
409                 ServerInstance->Logs->Log("m_ripemd160", DEBUG, "RMD: '%s' length=%u", (const char*)message, length);
410                 dword         MDbuf[RMDsize/32];   /* contains (A, B, C, D(, E))   */
411                 static byte   hashcode[RMDsize/8]; /* for final hash-value         */
412                 dword         X[16];               /* current 16-word chunk        */
413                 unsigned int  i;                   /* counter                      */
414                 dword         nbytes;              /* # of bytes not yet processed */
415
416                 /* initialize */
417                 MDinit(MDbuf, key);
418
419                 /* process message in 16-word chunks */
420                 for (nbytes=length; nbytes > 63; nbytes-=64) {
421                         for (i=0; i<16; i++) {
422                                 X[i] = BYTES_TO_DWORD(message);
423                                 message += 4;
424                         }
425                         compress(MDbuf, X);
426                 }                                    /* length mod 64 bytes left */
427
428                 MDfinish(MDbuf, message, length, 0);
429
430                 for (i=0; i<RMDsize/8; i+=4) {
431                         hashcode[i]   =  MDbuf[i>>2];         /* implicit cast to byte  */
432                         hashcode[i+1] = (MDbuf[i>>2] >>  8);  /*  extracts the 8 least  */
433                         hashcode[i+2] = (MDbuf[i>>2] >> 16);  /*  significant bits.     */
434                         hashcode[i+3] = (MDbuf[i>>2] >> 24);
435                 }
436
437                 return (byte *)hashcode;
438         }
439
440         unsigned int* currkey;
441         const char* chars;
442
443  public:
444
445         ModuleRIPEMD160(InspIRCd* Me) : Module(Me), currkey(NULL), chars("0123456789abcdef")
446         {
447                 ServerInstance->Modules->PublishInterface("HashRequest", this);
448                 Implementation eventlist[] = { I_OnRequest };
449                 ServerInstance->Modules->Attach(eventlist, this, 1);
450         }
451
452         virtual ~ModuleRIPEMD160()
453         {
454                 ServerInstance->Modules->UnpublishInterface("HashRequest", this);
455         }
456
457
458         virtual const char* OnRequest(Request* request)
459         {
460                 HashRequest* SHA = (HashRequest*)request;
461                 if (strcmp("KEY", request->GetId()) == 0)
462                 {
463                         this->currkey = (unsigned int*)SHA->GetKeyData();
464                 }
465                 else if (strcmp("HEX", request->GetId()) == 0)
466                 {
467                         this->chars = SHA->GetOutputs();
468                 }
469                 else if (strcmp("SUM", request->GetId()) == 0)
470                 {
471                         static char output[MAXBUF];
472                         unsigned char* data = (unsigned char*)RMD((byte *)SHA->GetHashData().data(),SHA->GetHashData().length(), currkey);
473                         int j = 0;
474                         for (int i = 0; i < RMDsize / 8; i++)
475                         {
476                                 output[j++] = chars[data[i] / 16];
477                                 output[j++] = chars[data[i] % 16];
478                                 ServerInstance->Logs->Log("m_ripemd160", DEBUG, "Hash: %02x", data[i]);
479                         }
480                         output[j] = '\0';
481                         return output;
482                 }
483                 else if (strcmp("NAME", request->GetId()) == 0)
484                 {
485                         return "ripemd160";
486                 }
487                 else if (strcmp("RESET", request->GetId()) == 0)
488                 {
489                         this->chars = "0123456789abcdef";
490                         this->currkey = NULL;
491                 }
492                 return NULL;
493         }
494
495         virtual Version GetVersion()
496         {
497                 return Version("Allows for RIPEMD-160 encrypted oper passwords", VF_VENDOR|VF_SERVICEPROVIDER, API_VERSION);
498         }
499
500 };
501
502 MODULE_INIT(ModuleRIPEMD160)
503