1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43:
44:
54: public class RipeMD160
55: extends BaseHash
56: {
57: private static final int BLOCK_SIZE = 64;
58:
59: private static final String DIGEST0 = "9C1185A5C5E9FC54612808977EE8F548B2258D31";
60:
61:
62: private static final int[] R = {
63: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
64: 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
65: 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
66: 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
67: 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13 };
68:
69: private static final int[] Rp = {
70: 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
71: 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
72: 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
73: 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
74: 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11 };
75:
76:
77: private static final int[] S = {
78: 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
79: 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
80: 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
81: 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
82: 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6 };
83:
84: private static final int[] Sp = {
85: 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
86: 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
87: 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
88: 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
89: 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 };
90:
91:
92: private static Boolean valid;
93:
94:
95: private int h0, h1, h2, h3, h4;
96:
97:
98: private int[] X = new int[16];
99:
100:
101: public RipeMD160()
102: {
103: super(Registry.RIPEMD160_HASH, 20, BLOCK_SIZE);
104: }
105:
106:
111: private RipeMD160(RipeMD160 md)
112: {
113: this();
114:
115: this.h0 = md.h0;
116: this.h1 = md.h1;
117: this.h2 = md.h2;
118: this.h3 = md.h3;
119: this.h4 = md.h4;
120: this.count = md.count;
121: this.buffer = (byte[]) md.buffer.clone();
122: }
123:
124: public Object clone()
125: {
126: return (new RipeMD160(this));
127: }
128:
129: protected void transform(byte[] in, int offset)
130: {
131: int A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, T, s, i;
132:
133: for (i = 0; i < 16; i++)
134: X[i] = (in[offset++] & 0xFF)
135: | (in[offset++] & 0xFF) << 8
136: | (in[offset++] & 0xFF) << 16
137: | in[offset++] << 24;
138: A = Ap = h0;
139: B = Bp = h1;
140: C = Cp = h2;
141: D = Dp = h3;
142: E = Ep = h4;
143: for (i = 0; i < 16; i++)
144: {
145: s = S[i];
146: T = A + (B ^ C ^ D) + X[i];
147: A = E;
148: E = D;
149: D = C << 10 | C >>> 22;
150: C = B;
151: B = (T << s | T >>> (32 - s)) + A;
152:
153: s = Sp[i];
154: T = Ap + (Bp ^ (Cp | ~Dp)) + X[Rp[i]] + 0x50A28BE6;
155: Ap = Ep;
156: Ep = Dp;
157: Dp = Cp << 10 | Cp >>> 22;
158: Cp = Bp;
159: Bp = (T << s | T >>> (32 - s)) + Ap;
160: }
161: for (; i < 32; i++)
162: {
163: s = S[i];
164: T = A + ((B & C) | (~B & D)) + X[R[i]] + 0x5A827999;
165: A = E;
166: E = D;
167: D = C << 10 | C >>> 22;
168: C = B;
169: B = (T << s | T >>> (32 - s)) + A;
170:
171: s = Sp[i];
172: T = Ap + ((Bp & Dp) | (Cp & ~Dp)) + X[Rp[i]] + 0x5C4DD124;
173: Ap = Ep;
174: Ep = Dp;
175: Dp = Cp << 10 | Cp >>> 22;
176: Cp = Bp;
177: Bp = (T << s | T >>> (32 - s)) + Ap;
178: }
179: for (; i < 48; i++)
180: {
181: s = S[i];
182: T = A + ((B | ~C) ^ D) + X[R[i]] + 0x6ED9EBA1;
183: A = E;
184: E = D;
185: D = C << 10 | C >>> 22;
186: C = B;
187: B = (T << s | T >>> (32 - s)) + A;
188:
189: s = Sp[i];
190: T = Ap + ((Bp | ~Cp) ^ Dp) + X[Rp[i]] + 0x6D703EF3;
191: Ap = Ep;
192: Ep = Dp;
193: Dp = Cp << 10 | Cp >>> 22;
194: Cp = Bp;
195: Bp = (T << s | T >>> (32 - s)) + Ap;
196: }
197: for (; i < 64; i++)
198: {
199: s = S[i];
200: T = A + ((B & D) | (C & ~D)) + X[R[i]] + 0x8F1BBCDC;
201: A = E;
202: E = D;
203: D = C << 10 | C >>> 22;
204: C = B;
205: B = (T << s | T >>> (32 - s)) + A;
206:
207: s = Sp[i];
208: T = Ap + ((Bp & Cp) | (~Bp & Dp)) + X[Rp[i]] + 0x7A6D76E9;
209: Ap = Ep;
210: Ep = Dp;
211: Dp = Cp << 10 | Cp >>> 22;
212: Cp = Bp;
213: Bp = (T << s | T >>> (32 - s)) + Ap;
214: }
215: for (; i < 80; i++)
216: {
217: s = S[i];
218: T = A + (B ^ (C | ~D)) + X[R[i]] + 0xA953FD4E;
219: A = E;
220: E = D;
221: D = C << 10 | C >>> 22;
222: C = B;
223: B = (T << s | T >>> (32 - s)) + A;
224:
225: s = Sp[i];
226: T = Ap + (Bp ^ Cp ^ Dp) + X[Rp[i]];
227: Ap = Ep;
228: Ep = Dp;
229: Dp = Cp << 10 | Cp >>> 22;
230: Cp = Bp;
231: Bp = (T << s | T >>> (32 - s)) + Ap;
232: }
233: T = h1 + C + Dp;
234: h1 = h2 + D + Ep;
235: h2 = h3 + E + Ap;
236: h3 = h4 + A + Bp;
237: h4 = h0 + B + Cp;
238: h0 = T;
239: }
240:
241: protected byte[] padBuffer()
242: {
243: int n = (int)(count % BLOCK_SIZE);
244: int padding = (n < 56) ? (56 - n) : (120 - n);
245: byte[] result = new byte[padding + 8];
246:
247: result[0] = (byte) 0x80;
248:
249: long bits = count << 3;
250: result[padding++] = (byte) bits;
251: result[padding++] = (byte)(bits >>> 8);
252: result[padding++] = (byte)(bits >>> 16);
253: result[padding++] = (byte)(bits >>> 24);
254: result[padding++] = (byte)(bits >>> 32);
255: result[padding++] = (byte)(bits >>> 40);
256: result[padding++] = (byte)(bits >>> 48);
257: result[padding ] = (byte)(bits >>> 56);
258: return result;
259: }
260:
261: protected byte[] getResult()
262: {
263: return new byte[] {
264: (byte) h0, (byte)(h0 >>> 8), (byte)(h0 >>> 16), (byte)(h0 >>> 24),
265: (byte) h1, (byte)(h1 >>> 8), (byte)(h1 >>> 16), (byte)(h1 >>> 24),
266: (byte) h2, (byte)(h2 >>> 8), (byte)(h2 >>> 16), (byte)(h2 >>> 24),
267: (byte) h3, (byte)(h3 >>> 8), (byte)(h3 >>> 16), (byte)(h3 >>> 24),
268: (byte) h4, (byte)(h4 >>> 8), (byte)(h4 >>> 16), (byte)(h4 >>> 24)
269: };
270: }
271:
272: protected void resetContext()
273: {
274:
275: h0 = 0x67452301;
276: h1 = 0xEFCDAB89;
277: h2 = 0x98BADCFE;
278: h3 = 0x10325476;
279: h4 = 0xC3D2E1F0;
280: }
281:
282: public boolean selfTest()
283: {
284: if (valid == null)
285: {
286: String d = Util.toString(new RipeMD160().digest());
287: valid = Boolean.valueOf(DIGEST0.equals(d));
288: }
289: return valid.booleanValue();
290: }
291: }