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