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