/********************************************************************\ * * FILE: rmd160.c * * CONTENTS: A sample C-implementation of the RIPEMD-160 * hash-function. * TARGET: any computer with an ANSI C compiler * * AUTHOR: Antoon Bosselaers, ESAT-COSIC * DATE: 1 March 1996 * VERSION: 1.0 * * Copyright (c) 1996 Katholieke Universiteit Leuven * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * \********************************************************************/ /* header files */ #include #include #include #include "RIPEMD160.h" /********************************************************************/ void MDinit(dword *MDbuf) { MDbuf[0] = 0x67452301UL; MDbuf[1] = 0xefcdab89UL; MDbuf[2] = 0x98badcfeUL; MDbuf[3] = 0x10325476UL; MDbuf[4] = 0xc3d2e1f0UL; return; } /********************************************************************/ void compress(dword *MDbuf, dword *X) { dword aa = MDbuf[0], bb = MDbuf[1], cc = MDbuf[2], dd = MDbuf[3], ee = MDbuf[4]; dword aaa = MDbuf[0], bbb = MDbuf[1], ccc = MDbuf[2], ddd = MDbuf[3], eee = MDbuf[4]; /* round 1 */ FF(aa, bb, cc, dd, ee, X[0], 11); FF(ee, aa, bb, cc, dd, X[1], 14); FF(dd, ee, aa, bb, cc, X[2], 15); FF(cc, dd, ee, aa, bb, X[3], 12); FF(bb, cc, dd, ee, aa, X[4], 5); FF(aa, bb, cc, dd, ee, X[5], 8); FF(ee, aa, bb, cc, dd, X[6], 7); FF(dd, ee, aa, bb, cc, X[7], 9); FF(cc, dd, ee, aa, bb, X[8], 11); FF(bb, cc, dd, ee, aa, X[9], 13); FF(aa, bb, cc, dd, ee, X[10], 14); FF(ee, aa, bb, cc, dd, X[11], 15); FF(dd, ee, aa, bb, cc, X[12], 6); FF(cc, dd, ee, aa, bb, X[13], 7); FF(bb, cc, dd, ee, aa, X[14], 9); FF(aa, bb, cc, dd, ee, X[15], 8); /* round 2 */ GG(ee, aa, bb, cc, dd, X[7], 7); GG(dd, ee, aa, bb, cc, X[4], 6); GG(cc, dd, ee, aa, bb, X[13], 8); GG(bb, cc, dd, ee, aa, X[1], 13); GG(aa, bb, cc, dd, ee, X[10], 11); GG(ee, aa, bb, cc, dd, X[6], 9); GG(dd, ee, aa, bb, cc, X[15], 7); GG(cc, dd, ee, aa, bb, X[3], 15); GG(bb, cc, dd, ee, aa, X[12], 7); GG(aa, bb, cc, dd, ee, X[0], 12); GG(ee, aa, bb, cc, dd, X[9], 15); GG(dd, ee, aa, bb, cc, X[5], 9); GG(cc, dd, ee, aa, bb, X[2], 11); GG(bb, cc, dd, ee, aa, X[14], 7); GG(aa, bb, cc, dd, ee, X[11], 13); GG(ee, aa, bb, cc, dd, X[8], 12); /* round 3 */ HH(dd, ee, aa, bb, cc, X[3], 11); HH(cc, dd, ee, aa, bb, X[10], 13); HH(bb, cc, dd, ee, aa, X[14], 6); HH(aa, bb, cc, dd, ee, X[4], 7); HH(ee, aa, bb, cc, dd, X[9], 14); HH(dd, ee, aa, bb, cc, X[15], 9); HH(cc, dd, ee, aa, bb, X[8], 13); HH(bb, cc, dd, ee, aa, X[1], 15); HH(aa, bb, cc, dd, ee, X[2], 14); HH(ee, aa, bb, cc, dd, X[7], 8); HH(dd, ee, aa, bb, cc, X[0], 13); HH(cc, dd, ee, aa, bb, X[6], 6); HH(bb, cc, dd, ee, aa, X[13], 5); HH(aa, bb, cc, dd, ee, X[11], 12); HH(ee, aa, bb, cc, dd, X[5], 7); HH(dd, ee, aa, bb, cc, X[12], 5); /* round 4 */ II(cc, dd, ee, aa, bb, X[1], 11); II(bb, cc, dd, ee, aa, X[9], 12); II(aa, bb, cc, dd, ee, X[11], 14); II(ee, aa, bb, cc, dd, X[10], 15); II(dd, ee, aa, bb, cc, X[0], 14); II(cc, dd, ee, aa, bb, X[8], 15); II(bb, cc, dd, ee, aa, X[12], 9); II(aa, bb, cc, dd, ee, X[4], 8); II(ee, aa, bb, cc, dd, X[13], 9); II(dd, ee, aa, bb, cc, X[3], 14); II(cc, dd, ee, aa, bb, X[7], 5); II(bb, cc, dd, ee, aa, X[15], 6); II(aa, bb, cc, dd, ee, X[14], 8); II(ee, aa, bb, cc, dd, X[5], 6); II(dd, ee, aa, bb, cc, X[6], 5); II(cc, dd, ee, aa, bb, X[2], 12); /* round 5 */ JJ(bb, cc, dd, ee, aa, X[4], 9); JJ(aa, bb, cc, dd, ee, X[0], 15); JJ(ee, aa, bb, cc, dd, X[5], 5); JJ(dd, ee, aa, bb, cc, X[9], 11); JJ(cc, dd, ee, aa, bb, X[7], 6); JJ(bb, cc, dd, ee, aa, X[12], 8); JJ(aa, bb, cc, dd, ee, X[2], 13); JJ(ee, aa, bb, cc, dd, X[10], 12); JJ(dd, ee, aa, bb, cc, X[14], 5); JJ(cc, dd, ee, aa, bb, X[1], 12); JJ(bb, cc, dd, ee, aa, X[3], 13); JJ(aa, bb, cc, dd, ee, X[8], 14); JJ(ee, aa, bb, cc, dd, X[11], 11); JJ(dd, ee, aa, bb, cc, X[6], 8); JJ(cc, dd, ee, aa, bb, X[15], 5); JJ(bb, cc, dd, ee, aa, X[13], 6); /* parallel round 1 */ JJJ(aaa, bbb, ccc, ddd, eee, X[5], 8); JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9); JJJ(ddd, eee, aaa, bbb, ccc, X[7], 9); JJJ(ccc, ddd, eee, aaa, bbb, X[0], 11); JJJ(bbb, ccc, ddd, eee, aaa, X[9], 13); JJJ(aaa, bbb, ccc, ddd, eee, X[2], 15); JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15); JJJ(ddd, eee, aaa, bbb, ccc, X[4], 5); JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7); JJJ(bbb, ccc, ddd, eee, aaa, X[6], 7); JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8); JJJ(eee, aaa, bbb, ccc, ddd, X[8], 11); JJJ(ddd, eee, aaa, bbb, ccc, X[1], 14); JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14); JJJ(bbb, ccc, ddd, eee, aaa, X[3], 12); JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6); /* parallel round 2 */ III(eee, aaa, bbb, ccc, ddd, X[6], 9); III(ddd, eee, aaa, bbb, ccc, X[11], 13); III(ccc, ddd, eee, aaa, bbb, X[3], 15); III(bbb, ccc, ddd, eee, aaa, X[7], 7); III(aaa, bbb, ccc, ddd, eee, X[0], 12); III(eee, aaa, bbb, ccc, ddd, X[13], 8); III(ddd, eee, aaa, bbb, ccc, X[5], 9); III(ccc, ddd, eee, aaa, bbb, X[10], 11); III(bbb, ccc, ddd, eee, aaa, X[14], 7); III(aaa, bbb, ccc, ddd, eee, X[15], 7); III(eee, aaa, bbb, ccc, ddd, X[8], 12); III(ddd, eee, aaa, bbb, ccc, X[12], 7); III(ccc, ddd, eee, aaa, bbb, X[4], 6); III(bbb, ccc, ddd, eee, aaa, X[9], 15); III(aaa, bbb, ccc, ddd, eee, X[1], 13); III(eee, aaa, bbb, ccc, ddd, X[2], 11); /* parallel round 3 */ HHH(ddd, eee, aaa, bbb, ccc, X[15], 9); HHH(ccc, ddd, eee, aaa, bbb, X[5], 7); HHH(bbb, ccc, ddd, eee, aaa, X[1], 15); HHH(aaa, bbb, ccc, ddd, eee, X[3], 11); HHH(eee, aaa, bbb, ccc, ddd, X[7], 8); HHH(ddd, eee, aaa, bbb, ccc, X[14], 6); HHH(ccc, ddd, eee, aaa, bbb, X[6], 6); HHH(bbb, ccc, ddd, eee, aaa, X[9], 14); HHH(aaa, bbb, ccc, ddd, eee, X[11], 12); HHH(eee, aaa, bbb, ccc, ddd, X[8], 13); HHH(ddd, eee, aaa, bbb, ccc, X[12], 5); HHH(ccc, ddd, eee, aaa, bbb, X[2], 14); HHH(bbb, ccc, ddd, eee, aaa, X[10], 13); HHH(aaa, bbb, ccc, ddd, eee, X[0], 13); HHH(eee, aaa, bbb, ccc, ddd, X[4], 7); HHH(ddd, eee, aaa, bbb, ccc, X[13], 5); /* parallel round 4 */ GGG(ccc, ddd, eee, aaa, bbb, X[8], 15); GGG(bbb, ccc, ddd, eee, aaa, X[6], 5); GGG(aaa, bbb, ccc, ddd, eee, X[4], 8); GGG(eee, aaa, bbb, ccc, ddd, X[1], 11); GGG(ddd, eee, aaa, bbb, ccc, X[3], 14); GGG(ccc, ddd, eee, aaa, bbb, X[11], 14); GGG(bbb, ccc, ddd, eee, aaa, X[15], 6); GGG(aaa, bbb, ccc, ddd, eee, X[0], 14); GGG(eee, aaa, bbb, ccc, ddd, X[5], 6); GGG(ddd, eee, aaa, bbb, ccc, X[12], 9); GGG(ccc, ddd, eee, aaa, bbb, X[2], 12); GGG(bbb, ccc, ddd, eee, aaa, X[13], 9); GGG(aaa, bbb, ccc, ddd, eee, X[9], 12); GGG(eee, aaa, bbb, ccc, ddd, X[7], 5); GGG(ddd, eee, aaa, bbb, ccc, X[10], 15); GGG(ccc, ddd, eee, aaa, bbb, X[14], 8); /* parallel round 5 */ FFF(bbb, ccc, ddd, eee, aaa, X[12], 8); FFF(aaa, bbb, ccc, ddd, eee, X[15], 5); FFF(eee, aaa, bbb, ccc, ddd, X[10], 12); FFF(ddd, eee, aaa, bbb, ccc, X[4], 9); FFF(ccc, ddd, eee, aaa, bbb, X[1], 12); FFF(bbb, ccc, ddd, eee, aaa, X[5], 5); FFF(aaa, bbb, ccc, ddd, eee, X[8], 14); FFF(eee, aaa, bbb, ccc, ddd, X[7], 6); FFF(ddd, eee, aaa, bbb, ccc, X[6], 8); FFF(ccc, ddd, eee, aaa, bbb, X[2], 13); FFF(bbb, ccc, ddd, eee, aaa, X[13], 6); FFF(aaa, bbb, ccc, ddd, eee, X[14], 5); FFF(eee, aaa, bbb, ccc, ddd, X[0], 15); FFF(ddd, eee, aaa, bbb, ccc, X[3], 13); FFF(ccc, ddd, eee, aaa, bbb, X[9], 11); FFF(bbb, ccc, ddd, eee, aaa, X[11], 11); /* combine results */ ddd += cc + MDbuf[1]; /* final result for MDbuf[0] */ MDbuf[1] = MDbuf[2] + dd + eee; MDbuf[2] = MDbuf[3] + ee + aaa; MDbuf[3] = MDbuf[4] + aa + bbb; MDbuf[4] = MDbuf[0] + bb + ccc; MDbuf[0] = ddd; return; } /********************************************************************/ void MDfinish(dword *MDbuf, byte *strptr, dword lswlen, dword mswlen) { unsigned int i; /* counter */ dword X[16]; /* message words */ memset(X, 0, 16 * sizeof(dword)); /* put bytes from strptr into X */ for (i = 0; i<(lswlen & 63); i++) { /* byte i goes into word X[i div 4] at pos. 8*(i mod 4) */ X[i >> 2] ^= (dword)*strptr++ << (8 * (i & 3)); } /* append the bit m_n == 1 */ X[(lswlen >> 2) & 15] ^= (dword)1 << (8 * (lswlen & 3) + 7); if ((lswlen & 63) > 55) { /* length goes to next block */ compress(MDbuf, X); memset(X, 0, 16 * sizeof(dword)); } /* append length in bits*/ X[14] = lswlen << 3; X[15] = (lswlen >> 29) | (mswlen << 3); compress(MDbuf, X); return; } /************************ end of file rmd160.c **********************/