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