The InspIRCd Project
Home | Developers | Wiki | Forums | Bug Tracker | SVN | Download
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

m_ripemd160.cpp

Go to the documentation of this file.
00001 /*       +------------------------------------+
00002  *       | Inspire Internet Relay Chat Daemon |
00003  *       +------------------------------------+
00004  *
00005  *  InspIRCd: (C) 2002-2008 InspIRCd Development Team
00006  * See: http://www.inspircd.org/wiki/index.php/Credits
00007  *
00008  * This program is free but copyrighted software; see
00009  *            the file COPYING for details.
00010  *
00011  * ---------------------------------------------------
00012  */
00013 
00014 /*
00015  *
00016  *      AUTHOR:   Antoon Bosselaers, ESAT-COSIC
00017  *      DATE:     1 March 1996
00018  *      VERSION:  1.0
00019  *
00020  *      Copyright (c) Katholieke Universiteit Leuven
00021  *      1996, All Rights Reserved
00022  *
00023  *  Conditions for use of the RIPEMD-160 Software
00024  *
00025  *  The RIPEMD-160 software is freely available for use under the terms and
00026  *  conditions described hereunder, which shall be deemed to be accepted by
00027  *  any user of the software and applicable on any use of the software:
00028  *
00029  *  1. K.U.Leuven Department of Electrical Engineering-ESAT/COSIC shall for
00030  *     all purposes be considered the owner of the RIPEMD-160 software and of
00031  *     all copyright, trade secret, patent or other intellectual property
00032  *     rights therein.
00033  *  2. The RIPEMD-160 software is provided on an "as is" basis without
00034  *     warranty of any sort, express or implied. K.U.Leuven makes no
00035  *     representation that the use of the software will not infringe any
00036  *     patent or proprietary right of third parties. User will indemnify
00037  *     K.U.Leuven and hold K.U.Leuven harmless from any claims or liabilities
00038  *     which may arise as a result of its use of the software. In no
00039  *     circumstances K.U.Leuven R&D will be held liable for any deficiency,
00040  *     fault or other mishappening with regard to the use or performance of
00041  *     the software.
00042  *  3. User agrees to give due credit to K.U.Leuven in scientific publications
00043  *     or communications in relation with the use of the RIPEMD-160 software
00044  *     as follows: RIPEMD-160 software written by Antoon Bosselaers,
00045  *     available at http://www.esat.kuleuven.be/~cosicart/ps/AB-9601/.
00046  *
00047  */
00048 
00049 
00050 /* $ModDesc: Allows for RIPEMD-160 encrypted oper passwords */
00051 /* $ModDep: m_hash.h */
00052 
00053 /* macro definitions */
00054 
00055 #include "inspircd.h"
00056 #ifdef HAS_STDINT
00057 #include <stdint.h>
00058 #endif
00059 #include "m_hash.h"
00060 
00061 #define RMDsize 160
00062 
00063 #ifndef HAS_STDINT
00064 typedef         unsigned char           byte;
00065 typedef         unsigned int            dword;
00066 #else
00067 typedef         uint8_t                 byte;
00068 typedef         uint32_t                dword;
00069 #endif
00070 
00071 /* collect four bytes into one word: */
00072 #define BYTES_TO_DWORD(strptr)                    \
00073             (((dword) *((strptr)+3) << 24) | \
00074              ((dword) *((strptr)+2) << 16) | \
00075              ((dword) *((strptr)+1) <<  8) | \
00076              ((dword) *(strptr)))
00077 
00078 /* ROL(x, n) cyclically rotates x over n bits to the left */
00079 /* x must be of an unsigned 32 bits type and 0 <= n < 32. */
00080 #define ROL(x, n)        (((x) << (n)) | ((x) >> (32-(n))))
00081 
00082 /* the five basic functions F(), G() and H() */
00083 #define F(x, y, z)        ((x) ^ (y) ^ (z))
00084 #define G(x, y, z)        (((x) & (y)) | (~(x) & (z)))
00085 #define H(x, y, z)        (((x) | ~(y)) ^ (z))
00086 #define I(x, y, z)        (((x) & (z)) | ((y) & ~(z)))
00087 #define J(x, y, z)        ((x) ^ ((y) | ~(z)))
00088 
00089 /* the ten basic operations FF() through III() */
00090 
00091 #define FF(a, b, c, d, e, x, s)        {\
00092       (a) += F((b), (c), (d)) + (x);\
00093       (a) = ROL((a), (s)) + (e);\
00094       (c) = ROL((c), 10);\
00095    }
00096 
00097 #define GG(a, b, c, d, e, x, s)        {\
00098       (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
00099       (a) = ROL((a), (s)) + (e);\
00100       (c) = ROL((c), 10);\
00101    }
00102 
00103 #define HH(a, b, c, d, e, x, s)        {\
00104       (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
00105       (a) = ROL((a), (s)) + (e);\
00106       (c) = ROL((c), 10);\
00107    }
00108 
00109 #define II(a, b, c, d, e, x, s)        {\
00110       (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
00111       (a) = ROL((a), (s)) + (e);\
00112       (c) = ROL((c), 10);\
00113    }
00114 
00115 #define JJ(a, b, c, d, e, x, s)        {\
00116       (a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\
00117       (a) = ROL((a), (s)) + (e);\
00118       (c) = ROL((c), 10);\
00119    }
00120 
00121 #define FFF(a, b, c, d, e, x, s)        {\
00122       (a) += F((b), (c), (d)) + (x);\
00123       (a) = ROL((a), (s)) + (e);\
00124       (c) = ROL((c), 10);\
00125    }
00126 
00127 #define GGG(a, b, c, d, e, x, s)        {\
00128       (a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\
00129       (a) = ROL((a), (s)) + (e);\
00130       (c) = ROL((c), 10);\
00131    }
00132 
00133 #define HHH(a, b, c, d, e, x, s)        {\
00134       (a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\
00135       (a) = ROL((a), (s)) + (e);\
00136       (c) = ROL((c), 10);\
00137    }
00138 
00139 #define III(a, b, c, d, e, x, s)        {\
00140       (a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\
00141       (a) = ROL((a), (s)) + (e);\
00142       (c) = ROL((c), 10);\
00143    }
00144 
00145 #define JJJ(a, b, c, d, e, x, s)        {\
00146       (a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\
00147       (a) = ROL((a), (s)) + (e);\
00148       (c) = ROL((c), 10);\
00149    }
00150 
00151 
00152 class ModuleRIPEMD160 : public Module
00153 {
00154 
00155         void MDinit(dword *MDbuf, unsigned int* key)
00156         {
00157                 if (key)
00158                 {
00159                         ServerInstance->Logs->Log("m_ripemd160.so", DEBUG, "initialize with custom mdbuf");
00160                         MDbuf[0] = key[0];
00161                         MDbuf[1] = key[1];
00162                         MDbuf[2] = key[2];
00163                         MDbuf[3] = key[3];
00164                         MDbuf[4] = key[4];
00165                 }
00166                 else
00167                 {
00168                         ServerInstance->Logs->Log("m_ripemd160.so", DEBUG, "initialize with default mdbuf");
00169                         MDbuf[0] = 0x67452301UL;
00170                         MDbuf[1] = 0xefcdab89UL;
00171                         MDbuf[2] = 0x98badcfeUL;
00172                         MDbuf[3] = 0x10325476UL;
00173                         MDbuf[4] = 0xc3d2e1f0UL;
00174                 }
00175                 return;
00176         }
00177 
00178 
00179         void compress(dword *MDbuf, dword *X)
00180         {
00181                 dword aa = MDbuf[0],  bb = MDbuf[1],  cc = MDbuf[2],
00182                         dd = MDbuf[3],  ee = MDbuf[4];
00183                 dword aaa = MDbuf[0], bbb = MDbuf[1], ccc = MDbuf[2],
00184                         ddd = MDbuf[3], eee = MDbuf[4];
00185 
00186                 /* round 1 */
00187                 FF(aa, bb, cc, dd, ee, X[ 0], 11);
00188                 FF(ee, aa, bb, cc, dd, X[ 1], 14);
00189                 FF(dd, ee, aa, bb, cc, X[ 2], 15);
00190                 FF(cc, dd, ee, aa, bb, X[ 3], 12);
00191                 FF(bb, cc, dd, ee, aa, X[ 4],  5);
00192                 FF(aa, bb, cc, dd, ee, X[ 5],  8);
00193                 FF(ee, aa, bb, cc, dd, X[ 6],  7);
00194                 FF(dd, ee, aa, bb, cc, X[ 7],  9);
00195                 FF(cc, dd, ee, aa, bb, X[ 8], 11);
00196                 FF(bb, cc, dd, ee, aa, X[ 9], 13);
00197                 FF(aa, bb, cc, dd, ee, X[10], 14);
00198                 FF(ee, aa, bb, cc, dd, X[11], 15);
00199                 FF(dd, ee, aa, bb, cc, X[12],  6);
00200                 FF(cc, dd, ee, aa, bb, X[13],  7);
00201                 FF(bb, cc, dd, ee, aa, X[14],  9);
00202                 FF(aa, bb, cc, dd, ee, X[15],  8);
00203 
00204                 /* round 2 */
00205                 GG(ee, aa, bb, cc, dd, X[ 7],  7);
00206                 GG(dd, ee, aa, bb, cc, X[ 4],  6);
00207                 GG(cc, dd, ee, aa, bb, X[13],  8);
00208                 GG(bb, cc, dd, ee, aa, X[ 1], 13);
00209                 GG(aa, bb, cc, dd, ee, X[10], 11);
00210                 GG(ee, aa, bb, cc, dd, X[ 6],  9);
00211                 GG(dd, ee, aa, bb, cc, X[15],  7);
00212                 GG(cc, dd, ee, aa, bb, X[ 3], 15);
00213                 GG(bb, cc, dd, ee, aa, X[12],  7);
00214                 GG(aa, bb, cc, dd, ee, X[ 0], 12);
00215                 GG(ee, aa, bb, cc, dd, X[ 9], 15);
00216                 GG(dd, ee, aa, bb, cc, X[ 5],  9);
00217                 GG(cc, dd, ee, aa, bb, X[ 2], 11);
00218                 GG(bb, cc, dd, ee, aa, X[14],  7);
00219                 GG(aa, bb, cc, dd, ee, X[11], 13);
00220                 GG(ee, aa, bb, cc, dd, X[ 8], 12);
00221 
00222                 /* round 3 */
00223                 HH(dd, ee, aa, bb, cc, X[ 3], 11);
00224                 HH(cc, dd, ee, aa, bb, X[10], 13);
00225                 HH(bb, cc, dd, ee, aa, X[14],  6);
00226                 HH(aa, bb, cc, dd, ee, X[ 4],  7);
00227                 HH(ee, aa, bb, cc, dd, X[ 9], 14);
00228                 HH(dd, ee, aa, bb, cc, X[15],  9);
00229                 HH(cc, dd, ee, aa, bb, X[ 8], 13);
00230                 HH(bb, cc, dd, ee, aa, X[ 1], 15);
00231                 HH(aa, bb, cc, dd, ee, X[ 2], 14);
00232                 HH(ee, aa, bb, cc, dd, X[ 7],  8);
00233                 HH(dd, ee, aa, bb, cc, X[ 0], 13);
00234                 HH(cc, dd, ee, aa, bb, X[ 6],  6);
00235                 HH(bb, cc, dd, ee, aa, X[13],  5);
00236                 HH(aa, bb, cc, dd, ee, X[11], 12);
00237                 HH(ee, aa, bb, cc, dd, X[ 5],  7);
00238                 HH(dd, ee, aa, bb, cc, X[12],  5);
00239 
00240                 /* round 4 */
00241                 II(cc, dd, ee, aa, bb, X[ 1], 11);
00242                 II(bb, cc, dd, ee, aa, X[ 9], 12);
00243                 II(aa, bb, cc, dd, ee, X[11], 14);
00244                 II(ee, aa, bb, cc, dd, X[10], 15);
00245                 II(dd, ee, aa, bb, cc, X[ 0], 14);
00246                 II(cc, dd, ee, aa, bb, X[ 8], 15);
00247                 II(bb, cc, dd, ee, aa, X[12],  9);
00248                 II(aa, bb, cc, dd, ee, X[ 4],  8);
00249                 II(ee, aa, bb, cc, dd, X[13],  9);
00250                 II(dd, ee, aa, bb, cc, X[ 3], 14);
00251                 II(cc, dd, ee, aa, bb, X[ 7],  5);
00252                 II(bb, cc, dd, ee, aa, X[15],  6);
00253                 II(aa, bb, cc, dd, ee, X[14],  8);
00254                 II(ee, aa, bb, cc, dd, X[ 5],  6);
00255                 II(dd, ee, aa, bb, cc, X[ 6],  5);
00256                 II(cc, dd, ee, aa, bb, X[ 2], 12);
00257 
00258                 /* round 5 */
00259                 JJ(bb, cc, dd, ee, aa, X[ 4],  9);
00260                 JJ(aa, bb, cc, dd, ee, X[ 0], 15);
00261                 JJ(ee, aa, bb, cc, dd, X[ 5],  5);
00262                 JJ(dd, ee, aa, bb, cc, X[ 9], 11);
00263                 JJ(cc, dd, ee, aa, bb, X[ 7],  6);
00264                 JJ(bb, cc, dd, ee, aa, X[12],  8);
00265                 JJ(aa, bb, cc, dd, ee, X[ 2], 13);
00266                 JJ(ee, aa, bb, cc, dd, X[10], 12);
00267                 JJ(dd, ee, aa, bb, cc, X[14],  5);
00268                 JJ(cc, dd, ee, aa, bb, X[ 1], 12);
00269                 JJ(bb, cc, dd, ee, aa, X[ 3], 13);
00270                 JJ(aa, bb, cc, dd, ee, X[ 8], 14);
00271                 JJ(ee, aa, bb, cc, dd, X[11], 11);
00272                 JJ(dd, ee, aa, bb, cc, X[ 6],  8);
00273                 JJ(cc, dd, ee, aa, bb, X[15],  5);
00274                 JJ(bb, cc, dd, ee, aa, X[13],  6);
00275 
00276                 /* parallel round 1 */
00277                 JJJ(aaa, bbb, ccc, ddd, eee, X[ 5],  8);
00278                 JJJ(eee, aaa, bbb, ccc, ddd, X[14],  9);
00279                 JJJ(ddd, eee, aaa, bbb, ccc, X[ 7],  9);
00280                 JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11);
00281                 JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13);
00282                 JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15);
00283                 JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15);
00284                 JJJ(ddd, eee, aaa, bbb, ccc, X[ 4],  5);
00285                 JJJ(ccc, ddd, eee, aaa, bbb, X[13],  7);
00286                 JJJ(bbb, ccc, ddd, eee, aaa, X[ 6],  7);
00287                 JJJ(aaa, bbb, ccc, ddd, eee, X[15],  8);
00288                 JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11);
00289                 JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14);
00290                 JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14);
00291                 JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12);
00292                 JJJ(aaa, bbb, ccc, ddd, eee, X[12],  6);
00293 
00294                 /* parallel round 2 */
00295                 III(eee, aaa, bbb, ccc, ddd, X[ 6],  9);
00296                 III(ddd, eee, aaa, bbb, ccc, X[11], 13);
00297                 III(ccc, ddd, eee, aaa, bbb, X[ 3], 15);
00298                 III(bbb, ccc, ddd, eee, aaa, X[ 7],  7);
00299                 III(aaa, bbb, ccc, ddd, eee, X[ 0], 12);
00300                 III(eee, aaa, bbb, ccc, ddd, X[13],  8);
00301                 III(ddd, eee, aaa, bbb, ccc, X[ 5],  9);
00302                 III(ccc, ddd, eee, aaa, bbb, X[10], 11);
00303                 III(bbb, ccc, ddd, eee, aaa, X[14],  7);
00304                 III(aaa, bbb, ccc, ddd, eee, X[15],  7);
00305                 III(eee, aaa, bbb, ccc, ddd, X[ 8], 12);
00306                 III(ddd, eee, aaa, bbb, ccc, X[12],  7);
00307                 III(ccc, ddd, eee, aaa, bbb, X[ 4],  6);
00308                 III(bbb, ccc, ddd, eee, aaa, X[ 9], 15);
00309                 III(aaa, bbb, ccc, ddd, eee, X[ 1], 13);
00310                 III(eee, aaa, bbb, ccc, ddd, X[ 2], 11);
00311 
00312                 /* parallel round 3 */
00313                 HHH(ddd, eee, aaa, bbb, ccc, X[15],  9);
00314                 HHH(ccc, ddd, eee, aaa, bbb, X[ 5],  7);
00315                 HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15);
00316                 HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11);
00317                 HHH(eee, aaa, bbb, ccc, ddd, X[ 7],  8);
00318                 HHH(ddd, eee, aaa, bbb, ccc, X[14],  6);
00319                 HHH(ccc, ddd, eee, aaa, bbb, X[ 6],  6);
00320                 HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14);
00321                 HHH(aaa, bbb, ccc, ddd, eee, X[11], 12);
00322                 HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13);
00323                 HHH(ddd, eee, aaa, bbb, ccc, X[12],  5);
00324                 HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14);
00325                 HHH(bbb, ccc, ddd, eee, aaa, X[10], 13);
00326                 HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13);
00327                 HHH(eee, aaa, bbb, ccc, ddd, X[ 4],  7);
00328                 HHH(ddd, eee, aaa, bbb, ccc, X[13],  5);
00329 
00330                 /* parallel round 4 */
00331                 GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15);
00332                 GGG(bbb, ccc, ddd, eee, aaa, X[ 6],  5);
00333                 GGG(aaa, bbb, ccc, ddd, eee, X[ 4],  8);
00334                 GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11);
00335                 GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14);
00336                 GGG(ccc, ddd, eee, aaa, bbb, X[11], 14);
00337                 GGG(bbb, ccc, ddd, eee, aaa, X[15],  6);
00338                 GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14);
00339                 GGG(eee, aaa, bbb, ccc, ddd, X[ 5],  6);
00340                 GGG(ddd, eee, aaa, bbb, ccc, X[12],  9);
00341                 GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12);
00342                 GGG(bbb, ccc, ddd, eee, aaa, X[13],  9);
00343                 GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12);
00344                 GGG(eee, aaa, bbb, ccc, ddd, X[ 7],  5);
00345                 GGG(ddd, eee, aaa, bbb, ccc, X[10], 15);
00346                 GGG(ccc, ddd, eee, aaa, bbb, X[14],  8);
00347 
00348                 /* parallel round 5 */
00349                 FFF(bbb, ccc, ddd, eee, aaa, X[12] ,  8);
00350                 FFF(aaa, bbb, ccc, ddd, eee, X[15] ,  5);
00351                 FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12);
00352                 FFF(ddd, eee, aaa, bbb, ccc, X[ 4] ,  9);
00353                 FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12);
00354                 FFF(bbb, ccc, ddd, eee, aaa, X[ 5] ,  5);
00355                 FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14);
00356                 FFF(eee, aaa, bbb, ccc, ddd, X[ 7] ,  6);
00357                 FFF(ddd, eee, aaa, bbb, ccc, X[ 6] ,  8);
00358                 FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13);
00359                 FFF(bbb, ccc, ddd, eee, aaa, X[13] ,  6);
00360                 FFF(aaa, bbb, ccc, ddd, eee, X[14] ,  5);
00361                 FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15);
00362                 FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13);
00363                 FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11);
00364                 FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11);
00365 
00366                 /* combine results */
00367                 ddd += cc + MDbuf[1];               /* final result for MDbuf[0] */
00368                 MDbuf[1] = MDbuf[2] + dd + eee;
00369                 MDbuf[2] = MDbuf[3] + ee + aaa;
00370                 MDbuf[3] = MDbuf[4] + aa + bbb;
00371                 MDbuf[4] = MDbuf[0] + bb + ccc;
00372                 MDbuf[0] = ddd;
00373 
00374                 return;
00375         }
00376 
00377         void MDfinish(dword *MDbuf, byte *strptr, dword lswlen, dword mswlen)
00378         {
00379                 unsigned int i;                                 /* counter       */
00380                 dword        X[16];                             /* message words */
00381 
00382                 memset(X, 0, sizeof(X));
00383 
00384                 /* put bytes from strptr into X */
00385                 for (i=0; i<(lswlen&63); i++) {
00386                         /* byte i goes into word X[i div 4] at pos.  8*(i mod 4)  */
00387                         X[i>>2] ^= (dword) *strptr++ << (8 * (i&3));
00388                 }
00389 
00390                 /* append the bit m_n == 1 */
00391                 X[(lswlen>>2)&15] ^= (dword)1 << (8*(lswlen&3) + 7);
00392 
00393                 if ((lswlen & 63) > 55) {
00394                         /* length goes to next block */
00395                         compress(MDbuf, X);
00396                         memset(X, 0, sizeof(X));
00397                 }
00398 
00399                 /* append length in bits*/
00400                 X[14] = lswlen << 3;
00401                 X[15] = (lswlen >> 29) | (mswlen << 3);
00402                 compress(MDbuf, X);
00403 
00404                 return;
00405         }
00406 
00407         byte *RMD(byte *message, dword length, unsigned int* key)
00408         {
00409                 ServerInstance->Logs->Log("m_ripemd160", DEBUG, "RMD: '%s' length=%u", (const char*)message, length);
00410                 dword         MDbuf[RMDsize/32];   /* contains (A, B, C, D(, E))   */
00411                 static byte   hashcode[RMDsize/8]; /* for final hash-value         */
00412                 dword         X[16];               /* current 16-word chunk        */
00413                 unsigned int  i;                   /* counter                      */
00414                 dword         nbytes;              /* # of bytes not yet processed */
00415 
00416                 /* initialize */
00417                 MDinit(MDbuf, key);
00418 
00419                 /* process message in 16-word chunks */
00420                 for (nbytes=length; nbytes > 63; nbytes-=64) {
00421                         for (i=0; i<16; i++) {
00422                                 X[i] = BYTES_TO_DWORD(message);
00423                                 message += 4;
00424                         }
00425                         compress(MDbuf, X);
00426                 }                                    /* length mod 64 bytes left */
00427 
00428                 MDfinish(MDbuf, message, length, 0);
00429 
00430                 for (i=0; i<RMDsize/8; i+=4) {
00431                         hashcode[i]   =  MDbuf[i>>2];         /* implicit cast to byte  */
00432                         hashcode[i+1] = (MDbuf[i>>2] >>  8);  /*  extracts the 8 least  */
00433                         hashcode[i+2] = (MDbuf[i>>2] >> 16);  /*  significant bits.     */
00434                         hashcode[i+3] = (MDbuf[i>>2] >> 24);
00435                 }
00436 
00437                 return (byte *)hashcode;
00438         }
00439 
00440         unsigned int* currkey;
00441         const char* chars;
00442 
00443  public:
00444 
00445         ModuleRIPEMD160(InspIRCd* Me) : Module(Me), currkey(NULL), chars("0123456789abcdef")
00446         {
00447                 ServerInstance->Modules->PublishInterface("HashRequest", this);
00448                 Implementation eventlist[] = { I_OnRequest };
00449                 ServerInstance->Modules->Attach(eventlist, this, 1);
00450         }
00451 
00452         virtual ~ModuleRIPEMD160()
00453         {
00454                 ServerInstance->Modules->UnpublishInterface("HashRequest", this);
00455         }
00456 
00457 
00458         virtual const char* OnRequest(Request* request)
00459         {
00460                 HashRequest* SHA = (HashRequest*)request;
00461                 if (strcmp("KEY", request->GetId()) == 0)
00462                 {
00463                         this->currkey = (unsigned int*)SHA->GetKeyData();
00464                 }
00465                 else if (strcmp("HEX", request->GetId()) == 0)
00466                 {
00467                         this->chars = SHA->GetOutputs();
00468                 }
00469                 else if (strcmp("SUM", request->GetId()) == 0)
00470                 {
00471                         static char output[MAXBUF];
00472                         unsigned char* data = (unsigned char*)RMD((byte *)SHA->GetHashData().data(),SHA->GetHashData().length(), currkey);
00473                         int j = 0;
00474                         for (int i = 0; i < RMDsize / 8; i++)
00475                         {
00476                                 output[j++] = chars[data[i] / 16];
00477                                 output[j++] = chars[data[i] % 16];
00478                                 ServerInstance->Logs->Log("m_ripemd160", DEBUG, "Hash: %02x", data[i]);
00479                         }
00480                         output[j] = '\0';
00481                         return output;
00482                 }
00483                 else if (strcmp("NAME", request->GetId()) == 0)
00484                 {
00485                         return "ripemd160";
00486                 }
00487                 else if (strcmp("RESET", request->GetId()) == 0)
00488                 {
00489                         this->chars = "0123456789abcdef";
00490                         this->currkey = NULL;
00491                 }
00492                 return NULL;
00493         }
00494 
00495         virtual Version GetVersion()
00496         {
00497                 return Version("$Id: m_ripemd160.cpp 10291 2008-08-25 20:35:51Z w00t $", VF_VENDOR|VF_SERVICEPROVIDER, API_VERSION);
00498         }
00499 
00500 };
00501 
00502 MODULE_INIT(ModuleRIPEMD160)
00503