RIPEMD 160是否有一个与SHA-2相同的填充方案(我可以共享一个我已经编写过的方法)?文档并没有完全清楚。我已经查看了我发现的所有文档和代码,并且我确信我已经正确设计了压缩功能,但代码并没有返回正确的结果。这是Java代码:
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";
}
}
就像我说pad方法返回一个与SHA-2一起工作的列表;告诉我你是否也需要看到它。你能看到我在这里做错了吗?
答案 0 :(得分:2)
如果我看一下reference implementation那么它似乎做了相同的位填充(使用memset
使用零值并写入零位),但它结束于:
/* append length in bits*/
X[14] = lswlen << 3;
X[15] = (lswlen >> 29) | (mswlen << 3);
compress(MDbuf, X);
所以我猜你也需要压缩消息长度,这可能是为了避免长度扩展攻击。
编译引用。实现并逐步执行或打印中间值以确定您的中间状态是否正确。