Source for gnu.java.security.hash.RipeMD160

   1: /* RipeMD160.java --
   2:    Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc.
   3: 
   4: This file is a part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2 of the License, or (at
   9: your option) any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; if not, write to the Free Software
  18: Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
  19: USA
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version.  */
  37: 
  38: 
  39: package gnu.java.security.hash;
  40: 
  41: import gnu.java.security.Registry;
  42: import gnu.java.security.util.Util;
  43: 
  44: /**
  45:  * RIPEMD-160 is a 160-bit message digest.
  46:  * <p>
  47:  * References:
  48:  * <ol>
  49:  *    <li><a href="http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html">
  50:  *    RIPEMD160</a>: A Strengthened Version of RIPEMD.<br>
  51:  *    Hans Dobbertin, Antoon Bosselaers and Bart Preneel.</li>
  52:  * </ol>
  53:  */
  54: public class RipeMD160
  55:     extends BaseHash
  56: {
  57:   private static final int BLOCK_SIZE = 64; // inner block size in bytes
  58: 
  59:   private static final String DIGEST0 = "9C1185A5C5E9FC54612808977EE8F548B2258D31";
  60: 
  61:   // selection of message word
  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:   // amount for rotate left (rol)
  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:   /** caches the result of the correctness test, once executed. */
  92:   private static Boolean valid;
  93: 
  94:   /** 160-bit h0, h1, h2, h3, h4 (interim result) */
  95:   private int h0, h1, h2, h3, h4;
  96: 
  97:   /** 512 bits work buffer = 16 x 32-bit words */
  98:   private int[] X = new int[16];
  99: 
 100:   /** Trivial 0-arguments constructor. */
 101:   public RipeMD160()
 102:   {
 103:     super(Registry.RIPEMD160_HASH, 20, BLOCK_SIZE);
 104:   }
 105: 
 106:   /**
 107:    * Private constructor for cloning purposes.
 108:    *
 109:    * @param md the instance to clone.
 110:    */
 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:     // encode 64 bytes from input block into an array of 16 unsigned integers
 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++) // rounds 0...15
 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++) // rounds 16...31
 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++) // rounds 32...47
 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++) // rounds 48...63
 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++) // rounds 64...79
 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:     // padding is always binary 1 followed by binary 0s
 247:     result[0] = (byte) 0x80;
 248:     // save number of bits, casting the long to an array of 8 bytes
 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:     // magic RIPEMD160 initialisation constants
 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: }