Imported GNU Classpath 0.90
[official-gcc.git] / libjava / classpath / gnu / java / security / hash / RipeMD160.java
blob642ffb32de6729fbc1f55f2ad15bc82b058f769b
1 /* RipeMD160.java --
2 Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc.
4 This file is a part of GNU Classpath.
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.
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.
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
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.
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. */
39 package gnu.java.security.hash;
41 import gnu.java.security.Registry;
42 import gnu.java.security.util.Util;
44 /**
45 * <p>RIPEMD-160 is a 160-bit message digest.</p>
47 * <p>References:</p>
49 * <ol>
50 * <li><a href="http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html">
51 * RIPEMD160</a>: A Strengthened Version of RIPEMD.<br>
52 * Hans Dobbertin, Antoon Bosselaers and Bart Preneel.</li>
53 * </ol>
55 public class RipeMD160 extends BaseHash
58 // Constants and variables
59 // -------------------------------------------------------------------------
61 private static final int BLOCK_SIZE = 64; // inner block size in bytes
63 private static final String DIGEST0 = "9C1185A5C5E9FC54612808977EE8F548B2258D31";
65 // selection of message word
66 private static final int[] R = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
67 13, 14, 15, 7, 4, 13, 1, 10, 6, 15, 3, 12, 0,
68 9, 5, 2, 14, 11, 8, 3, 10, 14, 4, 9, 15, 8,
69 1, 2, 7, 0, 6, 13, 11, 5, 12, 1, 9, 11, 10,
70 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, 4, 0,
71 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15,
72 13 };
74 private static final int[] Rp = { 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1,
75 10, 3, 12, 6, 11, 3, 7, 0, 13, 5, 10, 14,
76 15, 8, 12, 4, 9, 1, 2, 15, 5, 1, 3, 7, 14,
77 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, 8, 6, 4,
78 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
79 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0,
80 3, 9, 11 };
82 // amount for rotate left (rol)
83 private static final int[] S = { 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15,
84 6, 7, 9, 8, 7, 6, 8, 13, 11, 9, 7, 15, 7, 12,
85 15, 9, 11, 7, 13, 12, 11, 13, 6, 7, 14, 9,
86 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, 11, 12,
87 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5,
88 12, 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13,
89 14, 11, 8, 5, 6 };
91 private static final int[] Sp = { 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11,
92 14, 14, 12, 6, 9, 13, 15, 7, 12, 8, 9, 11,
93 7, 7, 12, 7, 6, 15, 13, 11, 9, 7, 15, 11, 8,
94 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, 15,
95 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5,
96 15, 8, 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6,
97 5, 15, 13, 11, 11 };
99 /** caches the result of the correctness test, once executed. */
100 private static Boolean valid;
102 /** 160-bit h0, h1, h2, h3, h4 (interim result) */
103 private int h0, h1, h2, h3, h4;
105 /** 512 bits work buffer = 16 x 32-bit words */
106 private int[] X = new int[16];
108 // Constructor(s)
109 // -------------------------------------------------------------------------
111 /** Trivial 0-arguments constructor. */
112 public RipeMD160()
114 super(Registry.RIPEMD160_HASH, 20, BLOCK_SIZE);
118 * <p>Private constructor for cloning purposes.</p>
120 * @param md the instance to clone.
122 private RipeMD160(RipeMD160 md)
124 this();
126 this.h0 = md.h0;
127 this.h1 = md.h1;
128 this.h2 = md.h2;
129 this.h3 = md.h3;
130 this.h4 = md.h4;
131 this.count = md.count;
132 this.buffer = (byte[]) md.buffer.clone();
135 // Class methods
136 // -------------------------------------------------------------------------
138 // Instance methods
139 // -------------------------------------------------------------------------
141 // java.lang.Cloneable interface implementation ----------------------------
143 public Object clone()
145 return (new RipeMD160(this));
148 // Implementation of concrete methods in BaseHash --------------------------
150 protected void transform(byte[] in, int offset)
152 int A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, T, s, i;
154 // encode 64 bytes from input block into an array of 16 unsigned integers
155 for (i = 0; i < 16; i++)
157 X[i] = (in[offset++] & 0xFF) | (in[offset++] & 0xFF) << 8
158 | (in[offset++] & 0xFF) << 16 | in[offset++] << 24;
161 A = Ap = h0;
162 B = Bp = h1;
163 C = Cp = h2;
164 D = Dp = h3;
165 E = Ep = h4;
167 for (i = 0; i < 16; i++)
168 { // rounds 0...15
169 s = S[i];
170 T = A + (B ^ C ^ D) + X[i];
171 A = E;
172 E = D;
173 D = C << 10 | C >>> 22;
174 C = B;
175 B = (T << s | T >>> (32 - s)) + A;
177 s = Sp[i];
178 T = Ap + (Bp ^ (Cp | ~Dp)) + X[Rp[i]] + 0x50A28BE6;
179 Ap = Ep;
180 Ep = Dp;
181 Dp = Cp << 10 | Cp >>> 22;
182 Cp = Bp;
183 Bp = (T << s | T >>> (32 - s)) + Ap;
186 for (; i < 32; i++)
187 { // rounds 16...31
188 s = S[i];
189 T = A + ((B & C) | (~B & D)) + X[R[i]] + 0x5A827999;
190 A = E;
191 E = D;
192 D = C << 10 | C >>> 22;
193 C = B;
194 B = (T << s | T >>> (32 - s)) + A;
196 s = Sp[i];
197 T = Ap + ((Bp & Dp) | (Cp & ~Dp)) + X[Rp[i]] + 0x5C4DD124;
198 Ap = Ep;
199 Ep = Dp;
200 Dp = Cp << 10 | Cp >>> 22;
201 Cp = Bp;
202 Bp = (T << s | T >>> (32 - s)) + Ap;
205 for (; i < 48; i++)
206 { // rounds 32...47
207 s = S[i];
208 T = A + ((B | ~C) ^ D) + X[R[i]] + 0x6ED9EBA1;
209 A = E;
210 E = D;
211 D = C << 10 | C >>> 22;
212 C = B;
213 B = (T << s | T >>> (32 - s)) + A;
215 s = Sp[i];
216 T = Ap + ((Bp | ~Cp) ^ Dp) + X[Rp[i]] + 0x6D703EF3;
217 Ap = Ep;
218 Ep = Dp;
219 Dp = Cp << 10 | Cp >>> 22;
220 Cp = Bp;
221 Bp = (T << s | T >>> (32 - s)) + Ap;
224 for (; i < 64; i++)
225 { // rounds 48...63
226 s = S[i];
227 T = A + ((B & D) | (C & ~D)) + X[R[i]] + 0x8F1BBCDC;
228 A = E;
229 E = D;
230 D = C << 10 | C >>> 22;
231 C = B;
232 B = (T << s | T >>> (32 - s)) + A;
234 s = Sp[i];
235 T = Ap + ((Bp & Cp) | (~Bp & Dp)) + X[Rp[i]] + 0x7A6D76E9;
236 Ap = Ep;
237 Ep = Dp;
238 Dp = Cp << 10 | Cp >>> 22;
239 Cp = Bp;
240 Bp = (T << s | T >>> (32 - s)) + Ap;
243 for (; i < 80; i++)
244 { // rounds 64...79
245 s = S[i];
246 T = A + (B ^ (C | ~D)) + X[R[i]] + 0xA953FD4E;
247 A = E;
248 E = D;
249 D = C << 10 | C >>> 22;
250 C = B;
251 B = (T << s | T >>> (32 - s)) + A;
253 s = Sp[i];
254 T = Ap + (Bp ^ Cp ^ Dp) + X[Rp[i]];
255 Ap = Ep;
256 Ep = Dp;
257 Dp = Cp << 10 | Cp >>> 22;
258 Cp = Bp;
259 Bp = (T << s | T >>> (32 - s)) + Ap;
262 T = h1 + C + Dp;
263 h1 = h2 + D + Ep;
264 h2 = h3 + E + Ap;
265 h3 = h4 + A + Bp;
266 h4 = h0 + B + Cp;
267 h0 = T;
270 protected byte[] padBuffer()
272 int n = (int) (count % BLOCK_SIZE);
273 int padding = (n < 56) ? (56 - n) : (120 - n);
274 byte[] result = new byte[padding + 8];
276 // padding is always binary 1 followed by binary 0s
277 result[0] = (byte) 0x80;
279 // save number of bits, casting the long to an array of 8 bytes
280 long bits = count << 3;
281 result[padding++] = (byte) bits;
282 result[padding++] = (byte) (bits >>> 8);
283 result[padding++] = (byte) (bits >>> 16);
284 result[padding++] = (byte) (bits >>> 24);
285 result[padding++] = (byte) (bits >>> 32);
286 result[padding++] = (byte) (bits >>> 40);
287 result[padding++] = (byte) (bits >>> 48);
288 result[padding] = (byte) (bits >>> 56);
290 return result;
293 protected byte[] getResult()
295 byte[] result = new byte[] { (byte) h0, (byte) (h0 >>> 8),
296 (byte) (h0 >>> 16), (byte) (h0 >>> 24),
297 (byte) h1, (byte) (h1 >>> 8),
298 (byte) (h1 >>> 16), (byte) (h1 >>> 24),
299 (byte) h2, (byte) (h2 >>> 8),
300 (byte) (h2 >>> 16), (byte) (h2 >>> 24),
301 (byte) h3, (byte) (h3 >>> 8),
302 (byte) (h3 >>> 16), (byte) (h3 >>> 24),
303 (byte) h4, (byte) (h4 >>> 8),
304 (byte) (h4 >>> 16), (byte) (h4 >>> 24) };
306 return result;
309 protected void resetContext()
311 // magic RIPEMD160 initialisation constants
312 h0 = 0x67452301;
313 h1 = 0xEFCDAB89;
314 h2 = 0x98BADCFE;
315 h3 = 0x10325476;
316 h4 = 0xC3D2E1F0;
319 public boolean selfTest()
321 if (valid == null)
323 valid = Boolean.valueOf
324 (DIGEST0.equals(Util.toString(new RipeMD160().digest())));
326 return valid.booleanValue();