1 /* $Id: RIPEMD160.java,v 1.7 2001/06/25 15:39:55 gelderen Exp $ 2 * 3 * Copyright (C) 1995-2000 The Cryptix Foundation Limited. 4 * All rights reserved. 5 * 6 * Use, modification, copying and distribution of this software is subject to 7 * the terms and conditions of the Cryptix General Licence. You should have 8 * received a copy of the Cryptix General Licence along with this library; 9 * if not, you can download a copy from http://www.cryptix.org/ . 10 */ 11 12 package cryptix.jce.provider.md; 13 14 15 /** 16 * Implements the RIPEMD160 message digest algorithm in Java as per the 17 * references below: 18 * 19 * <ul> 20 * <li> Hans Dobbertin, Antoon Bosselaers and Bart Preneel, 21 * "RIPEMD160: A Strengthened Version of RIPEMD," 18 April 1996. 22 * A joint publication by the German Information Security Agency 23 * (POB 20 03 63, D-53133 Bonn, Germany) 24 * and the Katholieke Universiteit Leuven, ESAT-COSIC 25 * (K. Mercierlaan 94, B-3001 Heverlee, Belgium).</li> 26 * <li><a href="http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html"> 27 * The hash function RIPEMD-160.</a></li> 28 * </ul> 29 * 30 * @version $Revision: 1.7 $ 31 * @author Raif S. Naffah 32 * @author David Hopwood 33 * @author Jeroen C. van Gelderen (gelderen@cryptix.org) 34 * @since Cryptix 2.2.2 35 */ 36 public final class RIPEMD160 37 extends PaddingMD 38 implements Cloneable 39 { 40 41 // Constants 42 //........................................................................... 43 44 /** 45 * Constants for the transform method. They're defined as static because 46 * they're common to all RIPEMD160 instantiated objects; and final since 47 * they're non-modifiable. 48 */ 49 private static final int[] 50 // selection of message word 51 R = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 52 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, 53 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, 54 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, 55 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13}, 56 Rp = { 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, 57 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, 58 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, 59 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, 60 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11}, 61 62 // amount for rotate left (rol) 63 S = { 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, 64 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, 65 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, 66 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, 67 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6}, 68 Sp = { 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, 69 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, 70 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, 71 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, 72 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11}; 73 74 75 /** Size of this hash (in bytes) */ 76 private static final int HASH_SIZE = 20; 77 78 79 80 // Instance variables 81 //........................................................................... 82 83 /** 160-bit h0, h1, h2, h3, h4 (interim result) */ 84 private int[] context = new int[5]; 85 86 87 /** 512 bits work buffer = 16 x 32-bit words */ 88 private int[] X = new int[16]; 89 90 91 92 // Constructors 93 //........................................................................... 94 RIPEMD160()95 public RIPEMD160() 96 { 97 super(HASH_SIZE, PaddingMD.MODE_MD); 98 coreReset(); 99 } 100 101 RIPEMD160(RIPEMD160 src)102 private RIPEMD160(RIPEMD160 src) 103 { 104 super(src); 105 this.context = (int[])src.context.clone(); 106 this.X = (int[])src.X.clone(); 107 } 108 109 clone()110 public Object clone() 111 { 112 return new RIPEMD160(this); 113 } 114 115 116 // Implementation 117 //........................................................................... 118 coreDigest(byte[] buf, int off)119 protected void coreDigest(byte[] buf, int off) 120 { 121 for (int i = 0; i < 5; i++) 122 for (int j = 0; j < 4; j++) 123 buf[off + (i * 4 + j)] = (byte)((context[i] >>> (8*j)) & 0xFF); 124 } 125 126 coreReset()127 protected void coreReset() 128 { 129 context[0] = 0x67452301; 130 context[1] = 0xEFCDAB89; 131 context[2] = 0x98BADCFE; 132 context[3] = 0x10325476; 133 context[4] = 0xC3D2E1F0; 134 } 135 136 137 /** 138 * RIPEMD160 basic transformation. 139 * <p> 140 * Transforms context based on 512 bits from input block starting from 141 * the offset'th byte. 142 */ coreUpdate(byte[] block, int offset)143 protected void coreUpdate(byte[] block, int offset) 144 { 145 int A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, T, s, i; 146 147 // encode 64 bytes from input block into an array of 16 unsigned 148 // integers. 149 for (i = 0; i < 16; i++) 150 X[i] = (block[offset++] & 0xFF) | 151 (block[offset++] & 0xFF) << 8 | 152 (block[offset++] & 0xFF) << 16 | 153 (block[offset++] & 0xFF) << 24; 154 155 A = Ap = context[0]; 156 B = Bp = context[1]; 157 C = Cp = context[2]; 158 D = Dp = context[3]; 159 E = Ep = context[4]; 160 161 // rounds 0...15 162 for (i = 0; i < 16; i++) 163 { 164 s = S[i]; 165 T = A + (B ^ C ^ D) + X[i]; 166 A = E; E = D; D = C << 10 | C >>> 22; C = B; 167 B = (T << s | T >>> (32 - s)) + A; 168 169 s = Sp[i]; 170 T = Ap + (Bp ^ (Cp | ~Dp)) + X[Rp[i]] + 0x50A28BE6; 171 Ap = Ep; Ep = Dp; Dp = Cp << 10 | Cp >>> 22; Cp = Bp; 172 Bp = (T << s | T >>> (32 - s)) + Ap; 173 } 174 // rounds 16...31 175 for (i = 16; i < 32; i++) 176 { 177 s = S[i]; 178 T = A + ((B & C) | (~B & D)) + X[R[i]] + 0x5A827999; 179 A = E; E = D; D = C << 10 | C >>> 22; C = B; 180 B = (T << s | T >>> (32 - s)) + A; 181 182 s = Sp[i]; 183 T = Ap + ((Bp & Dp) | (Cp & ~Dp)) + X[Rp[i]] + 0x5C4DD124; 184 Ap = Ep; Ep = Dp; Dp = Cp << 10 | Cp >>> 22; Cp = Bp; 185 Bp = (T << s | T >>> (32 - s)) + Ap; 186 } 187 // rounds 32...47 188 for (i = 32; i < 48; i++) 189 { 190 s = S[i]; 191 T = A + ((B | ~C) ^ D) + X[R[i]] + 0x6ED9EBA1; 192 A = E; E = D; D = C << 10 | C >>> 22; C = B; 193 B = (T << s | T >>> (32 - s)) + A; 194 195 s = Sp[i]; 196 T = Ap + ((Bp | ~Cp) ^ Dp) + X[Rp[i]] + 0x6D703EF3; 197 Ap = Ep; Ep = Dp; Dp = Cp << 10 | Cp >>> 22; Cp = Bp; 198 Bp = (T << s | T >>> (32 - s)) + Ap; 199 } 200 // rounds 48...63 201 for (i = 48; i < 64; i++) 202 { 203 s = S[i]; 204 T = A + ((B & D) | (C & ~D)) + X[R[i]] + 0x8F1BBCDC; 205 A = E; E = D; D = C << 10 | C >>> 22; C = B; 206 B = (T << s | T >>> (32 - s)) + A; 207 208 s = Sp[i]; 209 T = Ap + ((Bp & Cp) | (~Bp & Dp)) + X[Rp[i]] + 0x7A6D76E9; 210 Ap = Ep; Ep = Dp; Dp = Cp << 10 | Cp >>> 22; Cp = Bp; 211 Bp = (T << s | T >>> (32 - s)) + Ap; 212 } 213 // rounds 64...79 214 for (i = 64; i < 80; i++) 215 { 216 s = S[i]; 217 T = A + (B ^ (C | ~D)) + X[R[i]] + 0xA953FD4E; 218 A = E; E = D; D = C << 10 | C >>> 22; C = B; 219 B = (T << s | T >>> (32 - s)) + A; 220 221 s = Sp[i]; 222 T = Ap + (Bp ^ Cp ^ Dp) + X[Rp[i]]; 223 Ap = Ep; Ep = Dp; Dp = Cp << 10 | Cp >>> 22; Cp = Bp; 224 Bp = (T << s | T >>> (32 - s)) + Ap; 225 } 226 T = context[1] + C + Dp; 227 context[1] = context[2] + D + Ep; 228 context[2] = context[3] + E + Ap; 229 context[3] = context[4] + A + Bp; 230 context[4] = context[0] + B + Cp; 231 context[0] = T; 232 } 233 } 234