001: package org.bouncycastle.crypto.digests;
002:
003: /**
004: * implementation of RIPEMD128
005: */
006: public class RIPEMD128Digest extends GeneralDigest {
007: private static final int DIGEST_LENGTH = 16;
008:
009: private int H0, H1, H2, H3; // IV's
010:
011: private int[] X = new int[16];
012: private int xOff;
013:
014: /**
015: * Standard constructor
016: */
017: public RIPEMD128Digest() {
018: reset();
019: }
020:
021: /**
022: * Copy constructor. This will copy the state of the provided
023: * message digest.
024: */
025: public RIPEMD128Digest(RIPEMD128Digest t) {
026: super (t);
027:
028: H0 = t.H0;
029: H1 = t.H1;
030: H2 = t.H2;
031: H3 = t.H3;
032:
033: System.arraycopy(t.X, 0, X, 0, t.X.length);
034: xOff = t.xOff;
035: }
036:
037: public String getAlgorithmName() {
038: return "RIPEMD128";
039: }
040:
041: public int getDigestSize() {
042: return DIGEST_LENGTH;
043: }
044:
045: protected void processWord(byte[] in, int inOff) {
046: X[xOff++] = (in[inOff] & 0xff) | ((in[inOff + 1] & 0xff) << 8)
047: | ((in[inOff + 2] & 0xff) << 16)
048: | ((in[inOff + 3] & 0xff) << 24);
049:
050: if (xOff == 16) {
051: processBlock();
052: }
053: }
054:
055: protected void processLength(long bitLength) {
056: if (xOff > 14) {
057: processBlock();
058: }
059:
060: X[14] = (int) (bitLength & 0xffffffff);
061: X[15] = (int) (bitLength >>> 32);
062: }
063:
064: private void unpackWord(int word, byte[] out, int outOff) {
065: out[outOff] = (byte) word;
066: out[outOff + 1] = (byte) (word >>> 8);
067: out[outOff + 2] = (byte) (word >>> 16);
068: out[outOff + 3] = (byte) (word >>> 24);
069: }
070:
071: public int doFinal(byte[] out, int outOff) {
072: finish();
073:
074: unpackWord(H0, out, outOff);
075: unpackWord(H1, out, outOff + 4);
076: unpackWord(H2, out, outOff + 8);
077: unpackWord(H3, out, outOff + 12);
078:
079: reset();
080:
081: return DIGEST_LENGTH;
082: }
083:
084: /**
085: * reset the chaining variables to the IV values.
086: */
087: public void reset() {
088: super .reset();
089:
090: H0 = 0x67452301;
091: H1 = 0xefcdab89;
092: H2 = 0x98badcfe;
093: H3 = 0x10325476;
094:
095: xOff = 0;
096:
097: for (int i = 0; i != X.length; i++) {
098: X[i] = 0;
099: }
100: }
101:
102: /*
103: * rotate int x left n bits.
104: */
105: private final int RL(int x, int n) {
106: return (x << n) | (x >>> (32 - n));
107: }
108:
109: /*
110: * f1,f2,f3,f4 are the basic RIPEMD128 functions.
111: */
112:
113: /*
114: * F
115: */
116: private final int f1(int x, int y, int z) {
117: return x ^ y ^ z;
118: }
119:
120: /*
121: * G
122: */
123: private final int f2(int x, int y, int z) {
124: return (x & y) | (~x & z);
125: }
126:
127: /*
128: * H
129: */
130: private final int f3(int x, int y, int z) {
131: return (x | ~y) ^ z;
132: }
133:
134: /*
135: * I
136: */
137: private final int f4(int x, int y, int z) {
138: return (x & z) | (y & ~z);
139: }
140:
141: private final int F1(int a, int b, int c, int d, int x, int s) {
142: return RL(a + f1(b, c, d) + x, s);
143: }
144:
145: private final int F2(int a, int b, int c, int d, int x, int s) {
146: return RL(a + f2(b, c, d) + x + 0x5a827999, s);
147: }
148:
149: private final int F3(int a, int b, int c, int d, int x, int s) {
150: return RL(a + f3(b, c, d) + x + 0x6ed9eba1, s);
151: }
152:
153: private final int F4(int a, int b, int c, int d, int x, int s) {
154: return RL(a + f4(b, c, d) + x + 0x8f1bbcdc, s);
155: }
156:
157: private final int FF1(int a, int b, int c, int d, int x, int s) {
158: return RL(a + f1(b, c, d) + x, s);
159: }
160:
161: private final int FF2(int a, int b, int c, int d, int x, int s) {
162: return RL(a + f2(b, c, d) + x + 0x6d703ef3, s);
163: }
164:
165: private final int FF3(int a, int b, int c, int d, int x, int s) {
166: return RL(a + f3(b, c, d) + x + 0x5c4dd124, s);
167: }
168:
169: private final int FF4(int a, int b, int c, int d, int x, int s) {
170: return RL(a + f4(b, c, d) + x + 0x50a28be6, s);
171: }
172:
173: protected void processBlock() {
174: int a, aa;
175: int b, bb;
176: int c, cc;
177: int d, dd;
178:
179: a = aa = H0;
180: b = bb = H1;
181: c = cc = H2;
182: d = dd = H3;
183:
184: //
185: // Round 1
186: //
187: a = F1(a, b, c, d, X[0], 11);
188: d = F1(d, a, b, c, X[1], 14);
189: c = F1(c, d, a, b, X[2], 15);
190: b = F1(b, c, d, a, X[3], 12);
191: a = F1(a, b, c, d, X[4], 5);
192: d = F1(d, a, b, c, X[5], 8);
193: c = F1(c, d, a, b, X[6], 7);
194: b = F1(b, c, d, a, X[7], 9);
195: a = F1(a, b, c, d, X[8], 11);
196: d = F1(d, a, b, c, X[9], 13);
197: c = F1(c, d, a, b, X[10], 14);
198: b = F1(b, c, d, a, X[11], 15);
199: a = F1(a, b, c, d, X[12], 6);
200: d = F1(d, a, b, c, X[13], 7);
201: c = F1(c, d, a, b, X[14], 9);
202: b = F1(b, c, d, a, X[15], 8);
203:
204: //
205: // Round 2
206: //
207: a = F2(a, b, c, d, X[7], 7);
208: d = F2(d, a, b, c, X[4], 6);
209: c = F2(c, d, a, b, X[13], 8);
210: b = F2(b, c, d, a, X[1], 13);
211: a = F2(a, b, c, d, X[10], 11);
212: d = F2(d, a, b, c, X[6], 9);
213: c = F2(c, d, a, b, X[15], 7);
214: b = F2(b, c, d, a, X[3], 15);
215: a = F2(a, b, c, d, X[12], 7);
216: d = F2(d, a, b, c, X[0], 12);
217: c = F2(c, d, a, b, X[9], 15);
218: b = F2(b, c, d, a, X[5], 9);
219: a = F2(a, b, c, d, X[2], 11);
220: d = F2(d, a, b, c, X[14], 7);
221: c = F2(c, d, a, b, X[11], 13);
222: b = F2(b, c, d, a, X[8], 12);
223:
224: //
225: // Round 3
226: //
227: a = F3(a, b, c, d, X[3], 11);
228: d = F3(d, a, b, c, X[10], 13);
229: c = F3(c, d, a, b, X[14], 6);
230: b = F3(b, c, d, a, X[4], 7);
231: a = F3(a, b, c, d, X[9], 14);
232: d = F3(d, a, b, c, X[15], 9);
233: c = F3(c, d, a, b, X[8], 13);
234: b = F3(b, c, d, a, X[1], 15);
235: a = F3(a, b, c, d, X[2], 14);
236: d = F3(d, a, b, c, X[7], 8);
237: c = F3(c, d, a, b, X[0], 13);
238: b = F3(b, c, d, a, X[6], 6);
239: a = F3(a, b, c, d, X[13], 5);
240: d = F3(d, a, b, c, X[11], 12);
241: c = F3(c, d, a, b, X[5], 7);
242: b = F3(b, c, d, a, X[12], 5);
243:
244: //
245: // Round 4
246: //
247: a = F4(a, b, c, d, X[1], 11);
248: d = F4(d, a, b, c, X[9], 12);
249: c = F4(c, d, a, b, X[11], 14);
250: b = F4(b, c, d, a, X[10], 15);
251: a = F4(a, b, c, d, X[0], 14);
252: d = F4(d, a, b, c, X[8], 15);
253: c = F4(c, d, a, b, X[12], 9);
254: b = F4(b, c, d, a, X[4], 8);
255: a = F4(a, b, c, d, X[13], 9);
256: d = F4(d, a, b, c, X[3], 14);
257: c = F4(c, d, a, b, X[7], 5);
258: b = F4(b, c, d, a, X[15], 6);
259: a = F4(a, b, c, d, X[14], 8);
260: d = F4(d, a, b, c, X[5], 6);
261: c = F4(c, d, a, b, X[6], 5);
262: b = F4(b, c, d, a, X[2], 12);
263:
264: //
265: // Parallel round 1
266: //
267: aa = FF4(aa, bb, cc, dd, X[5], 8);
268: dd = FF4(dd, aa, bb, cc, X[14], 9);
269: cc = FF4(cc, dd, aa, bb, X[7], 9);
270: bb = FF4(bb, cc, dd, aa, X[0], 11);
271: aa = FF4(aa, bb, cc, dd, X[9], 13);
272: dd = FF4(dd, aa, bb, cc, X[2], 15);
273: cc = FF4(cc, dd, aa, bb, X[11], 15);
274: bb = FF4(bb, cc, dd, aa, X[4], 5);
275: aa = FF4(aa, bb, cc, dd, X[13], 7);
276: dd = FF4(dd, aa, bb, cc, X[6], 7);
277: cc = FF4(cc, dd, aa, bb, X[15], 8);
278: bb = FF4(bb, cc, dd, aa, X[8], 11);
279: aa = FF4(aa, bb, cc, dd, X[1], 14);
280: dd = FF4(dd, aa, bb, cc, X[10], 14);
281: cc = FF4(cc, dd, aa, bb, X[3], 12);
282: bb = FF4(bb, cc, dd, aa, X[12], 6);
283:
284: //
285: // Parallel round 2
286: //
287: aa = FF3(aa, bb, cc, dd, X[6], 9);
288: dd = FF3(dd, aa, bb, cc, X[11], 13);
289: cc = FF3(cc, dd, aa, bb, X[3], 15);
290: bb = FF3(bb, cc, dd, aa, X[7], 7);
291: aa = FF3(aa, bb, cc, dd, X[0], 12);
292: dd = FF3(dd, aa, bb, cc, X[13], 8);
293: cc = FF3(cc, dd, aa, bb, X[5], 9);
294: bb = FF3(bb, cc, dd, aa, X[10], 11);
295: aa = FF3(aa, bb, cc, dd, X[14], 7);
296: dd = FF3(dd, aa, bb, cc, X[15], 7);
297: cc = FF3(cc, dd, aa, bb, X[8], 12);
298: bb = FF3(bb, cc, dd, aa, X[12], 7);
299: aa = FF3(aa, bb, cc, dd, X[4], 6);
300: dd = FF3(dd, aa, bb, cc, X[9], 15);
301: cc = FF3(cc, dd, aa, bb, X[1], 13);
302: bb = FF3(bb, cc, dd, aa, X[2], 11);
303:
304: //
305: // Parallel round 3
306: //
307: aa = FF2(aa, bb, cc, dd, X[15], 9);
308: dd = FF2(dd, aa, bb, cc, X[5], 7);
309: cc = FF2(cc, dd, aa, bb, X[1], 15);
310: bb = FF2(bb, cc, dd, aa, X[3], 11);
311: aa = FF2(aa, bb, cc, dd, X[7], 8);
312: dd = FF2(dd, aa, bb, cc, X[14], 6);
313: cc = FF2(cc, dd, aa, bb, X[6], 6);
314: bb = FF2(bb, cc, dd, aa, X[9], 14);
315: aa = FF2(aa, bb, cc, dd, X[11], 12);
316: dd = FF2(dd, aa, bb, cc, X[8], 13);
317: cc = FF2(cc, dd, aa, bb, X[12], 5);
318: bb = FF2(bb, cc, dd, aa, X[2], 14);
319: aa = FF2(aa, bb, cc, dd, X[10], 13);
320: dd = FF2(dd, aa, bb, cc, X[0], 13);
321: cc = FF2(cc, dd, aa, bb, X[4], 7);
322: bb = FF2(bb, cc, dd, aa, X[13], 5);
323:
324: //
325: // Parallel round 4
326: //
327: aa = FF1(aa, bb, cc, dd, X[8], 15);
328: dd = FF1(dd, aa, bb, cc, X[6], 5);
329: cc = FF1(cc, dd, aa, bb, X[4], 8);
330: bb = FF1(bb, cc, dd, aa, X[1], 11);
331: aa = FF1(aa, bb, cc, dd, X[3], 14);
332: dd = FF1(dd, aa, bb, cc, X[11], 14);
333: cc = FF1(cc, dd, aa, bb, X[15], 6);
334: bb = FF1(bb, cc, dd, aa, X[0], 14);
335: aa = FF1(aa, bb, cc, dd, X[5], 6);
336: dd = FF1(dd, aa, bb, cc, X[12], 9);
337: cc = FF1(cc, dd, aa, bb, X[2], 12);
338: bb = FF1(bb, cc, dd, aa, X[13], 9);
339: aa = FF1(aa, bb, cc, dd, X[9], 12);
340: dd = FF1(dd, aa, bb, cc, X[7], 5);
341: cc = FF1(cc, dd, aa, bb, X[10], 15);
342: bb = FF1(bb, cc, dd, aa, X[14], 8);
343:
344: dd += c + H1; // final result for H0
345:
346: //
347: // combine the results
348: //
349: H1 = H2 + d + aa;
350: H2 = H3 + a + bb;
351: H3 = H0 + b + cc;
352: H0 = dd;
353:
354: //
355: // reset the offset and clean out the word buffer.
356: //
357: xOff = 0;
358: for (int i = 0; i != X.length; i++) {
359: X[i] = 0;
360: }
361: }
362: }
|