Does RIPEMD 160 have a padding scheme that is identical to SHA-2 (to the point I could share a method I already write that works with it)? The documentation doesn't make it entirely clear. I've gone over all documentation and code I've found and I'm sure I've got the design of the compression function right but the code doesn't return the correct result. Here's the Java code:
public class RIPEMD160 implements HashAlgorithm {
/**
* Message word left.
*/
private static final int[] R_LEFT = {
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 };
/**
* Message word right.
*/
private static final int[] R_RIGHT = {
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 };
/**
* Rotate left.
*/
private static final int[] S_LEFT = {
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 };
/**
* Rotate right.
*/
private static final int[] S_RIGHT = {
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 };
@Override
public String getHashDigest(String message) {
List<Integer> padded = HashUtils.pad512(message);
int blocks = padded.size() / 16;
//Set hash registers to initial values.
int h0 = 0x67452301;
int h1 = 0xefcdab89;
int h2 = 0x98badcfe;
int h3 = 0x10325476;
int h4 = 0xc3d2e1f0;
int index = 0;
int[] x = new int[16];
for (int i = 0; i < blocks; i++) {
//Push block words into array
for(int j = 0; j < 16; j++) {
x[j] = padded.get(index++);
} //f
//Left hand side registers.
int a1 = h0;
int b1 = h1;
int c1 = h2;
int d1 = h3;
int e1 = h4;
//Right hand side registers.
int a2 = h0;
int b2 = h1;
int c2 = h2;
int d2 = h3;
int e2 = h4;
//Temp values;
int t;
//Compression function. Made up of two lots of 5 sub blocks.
for(int j = 0; j < 80; j++) {
t = a1 + nonlinearFunction(j, b1, c1, d1) + x[R_LEFT[j]] + leftK(j);
a1 = e1;
e1 = d1;
d1 = rotateLeft(c1, 10);
c1 = b1;
b1 = rotateLeft(t, S_LEFT[j]) + a1;
t = a2 + nonlinearFunction(79 - j, b2, c2, d2) + x[R_RIGHT[j]] + rightK(j);
a2 = e2;
e2 = d2;
d2 = rotateLeft(c2, 10);
c2 = b2;
b2 = rotateLeft(t, S_RIGHT[j]) + a2;
} //f
//Mixing at bottom.
t = h1 + c1 + d2;
h1 = h2 + d1 + e2;
h2 = h3 + e1 + a2;
h3 = h4 + a1 + b2;
h4 = h0 + b1 + c2;
h0 = t;
} //f
return HashUtils.paddedHexadeciaml(h0)
+ HashUtils.paddedHexadeciaml(h1)
+ HashUtils.paddedHexadeciaml(h2)
+ HashUtils.paddedHexadeciaml(h3)
+ HashUtils.paddedHexadeciaml(h4);
}
private int rotateLeft(int x, int r) {
return (x << r) | (x >>> (32 - r));
}
private int nonlinearFunction(int j, int x, int y, int z) {
if (j <= 15) {
return x ^ y ^ z;
} else if (j <= 31) {
return (x & y) | (~x & z);
} else if (j <= 47) {
return (x | ~y) ^ z;
} else if (j <= 63) {
return (x & z) | (y & ~z);
} else {
return x ^ (y | ~z);
} //iel
}
private int leftK(int j) {
if (j <= 15) {
return 0;
} else if (j <= 31) {
return 0x5a827999;
} else if (j <= 47) {
return 0x6ed9eba1;
} else if (j <= 63) {
return 0x8f1bbcdc;
} else {
return 0xa953fd4e;
} //iel
}
private int rightK(int j) {
if (j <= 15) {
return 0x50a28be6;
} else if (j <= 31) {
return 0x5c4dd124;
} else if (j <= 47) {
return 0x6d703ef3;
} else if (j <= 63) {
return 0x7a6d76e9;
} else {
return 0;
} //iel
}
@Override
public String getAlgorithmName() {
return "RIPEMD160";
}
}
Like I said the pad method returns a list that works with SHA-2; tell me if you need to see it too. Can you see what I'm doing wrong here?