RIPEMD-160 uses precisely the same padding and endianess convention as MD5.
Everything is little-endian, with the exception of the order of bits in bytes, which is kept big-endian. If the message is $n$-bit, it is appended a single bit at 1
and $511-((n+64)\bmod512)$ bit(s) at 0
, then the representation of $n$ on 64 bits. The resulting padded message is an integral number of 512-bit blocks, which are each considered 16 words of 32 bits.
Note: It follows that the padding bit at 1
corresponds to a byte mask with value $2^{7-(n\bmod 8)}$. The $n\bmod 8$ last message bit(s) are in the high-order bit(s) of that byte, which $7-(n\bmod 8)$ low-order bit(s) are 0.
Suppose the message is the one-character string "a", and that is coded in ASCII as the single byte 61h = 01100001b = 97.
That's the bitstring 01100001
. $n=8$, thus the padding is 1
followed by 439 0
(with the first eight bits of that padding 10000000
corresponding to byte 80h), followed by the length $n=8$ represented as the bitstring 00001000 00000000 00000000 00000000 0000000 00000000 00000000 0000000
(with the first eight bits 00001000
corresponding to the byte 08h).
Showing this as a string of 64 bytes with bytes and 32-bit boundaries shown (and individual bytes shown in big-endian hexadecimal), the padded block is
61 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00
Packing that into 32-bit words using little-endian convention (and individual 32-bit words shown in big-endian hexadecimal), we get
00008061 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000008 00000000
or in decimal { 32865, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0 }
.
Note: a former version of this answer did not take into account the exception to little-endianness in the conversion of bytes to/from bits, and used uppercase ASCII code in the example. I'm confident about the present revised version.
Simple demonstration and example output for the reference code rmd160
// Demonstration of rmd160 - public domain
// note: on machines with more than 32-bit unsigned long, rmd160.h requires a simple change
#include "rmd160.h" // at http://homes.esat.kuleuven.be/~bosselae/ripemd160/ps/AB-9601/rmd160.h
#define SIZEOFHASH 20 // size of the hash in bytes
#define SIZEOFBLOCK 64 // size of a block in bytes
// including the code simplifies compilation+linking into a tool
#include "rmd160.c" // at http://homes.esat.kuleuven.be/~bosselae/ripemd160/ps/AB-9601/rmd160.c
// hash a byte buffer in memory
void hashmd160(
const byte *iData, // input
size_t iDataLength, // size of input in bytes
byte oHash[SIZEOFHASH] // result (must be allocated by caller)
)
{
dword vHash32[SIZEOFHASH%4==0 ? SIZEOFHASH/4 : -1 ]; // the hash, as 32-bit words
dword vBlock32[SIZEOFBLOCK%4==0 ? SIZEOFBLOCK/4 : -1 ]; // a block, as 32-bit words
size_t vb;
int vj;
// start hashing
MDinit(vHash32);
// hash full blocks; needed only when iDataLength>=SIZEOFBLOCK
for (vb = iDataLength/SIZEOFBLOCK; vb!=0; --vb)
{ // make a little-endian copy of SIZEOFBLOCK bytes from iData to vBlock32
for (vj = 0; vj<SIZEOFBLOCK/4; ++vj, iData += 4)
vBlock32[vj] = iData[0] | iData[1]<<8 | (dword)(iData[2] | iData[3]<<8)<<16;
compress(vHash32,vBlock32);
}
// hash remaining bytes
MDfinish(vHash32, (byte *)iData, iDataLength, iDataLength>>16>>16);
// make a little-endian copy of SIZEOFHASH bytes from vHash32 to oHash
for (vj = 0; vj<SIZEOFHASH; ++vj)
oHash[vj] = (byte)(vHash32[vj>>2]>>((vj&3)<<3));
}
// hash each argument, print its hash and the (quoted) argument
int main(int argc, char *argv[])
{
byte vHash[SIZEOFHASH];
int vj,va;
for(va=1; va<argc; ++va) {
hashmd160((const byte *)(argv[va]),strlen(argv[va]),vHash);
for (vj = 0; vj<SIZEOFHASH; ++vj)
printf("%02x",vHash[vj]);
printf(" \"%s\"\n",argv[va]);
}
return EXIT_SUCCESS;
}
/* Example output
9c1185a5c5e9fc54612808977ee8f548b2258d31 ""
0bdc9d2d256b3ee9daae347be6f4dc835a467ffe "a"
8eb208f7e05d987a9b044a8e98c6b087f15a0bfc "abc"
5d0689ef49d2fae572b881b123a85ffa21595f36 "message digest"
f71c27109c692c1b56bbdceb5b9d2865b3708dbc "abcdefghijklmnopqrstuvwxyz"
12a053384a9c0c88e405a06c27dcf49ada62eb2b "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
b0e20b6e3116640286ed3a87a5713079b21f5189 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
9b752e45573d4b39f4dbd3323cab82bf63326bfb "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
*/