2002/03/21 01:19:32
[org.ibex.core.git] / src / org / bouncycastle / crypto / digests / MD2Digest.java
1 package org.bouncycastle.crypto.digests;\r
2
3 import org.bouncycastle.crypto.Digest;
4 /**
5  * implementation of MD2
6  * as outlined in RFC1319 by B.Kaliski from RSA Laboratories April 1992
7  *
8  * @author Michael Lee
9  */
10 public class MD2Digest\r
11     implements Digest\r
12 {\r
13     private static final int DIGEST_LENGTH = 16;\r
14 \r
15     /* X buffer */\r
16     private byte[]   X = new byte[48];\r
17     private int     xOff;
18 \r    /* M buffer */
19 \r    private byte[]   M = new byte[16];\r
20     private int     mOff;
21 \r    /* check sum */
22 \r    private byte[]   C = new byte[16];
23     private int COff;
24
25     public MD2Digest()\r
26     {\r
27         reset();\r
28     }\r
29         public MD2Digest(MD2Digest t)\r
30         {
31                 System.arraycopy(t.X, 0, X, 0, t.X.length);
32                 xOff = t.xOff;
33                 System.arraycopy(t.M, 0, M, 0, t.M.length);
34                 mOff = t.mOff;
35                 System.arraycopy(t.C, 0, C, 0, t.C.length);
36                 COff = t.COff;
37         }
38     /**\r
39      * return the algorithm name
40      *
41      * @return the algorithm name
42      */
43     public String getAlgorithmName()
44     {
45         return "MD2";
46     }
47     /**
48      * return the size, in bytes, of the digest produced by this message digest.
49      *
50      * @return the size, in bytes, of the digest produced by this message digest.
51      */
52         public int getDigestSize()
53     {
54         return DIGEST_LENGTH;
55     }
56     /**
57      * close the digest, producing the final digest value. The doFinal
58      * call leaves the digest reset.
59      *
60      * @param out the array the digest is to be copied into.
61      * @param outOff the offset into the out array the digest is to start at.
62      */
63         public int doFinal(byte[] out, int outOff)
64     {
65         // add padding
66         byte paddingByte = (byte)(M.length-mOff);
67         for (int i=mOff;i<M.length;i++)
68         {
69             M[i] = paddingByte;
70         }
71         //do final check sum
72         processCheckSum(M);
73         // do final block process
74         processBlock(M);
75
76         processBlock(C);
77
78         System.arraycopy(X,xOff,out,outOff,16);
79
80         reset();
81
82         return DIGEST_LENGTH;
83     }
84     /**
85      * reset the digest back to it's initial state.
86      */
87     public void reset()\r
88     {\r
89         xOff = 0;\r
90         for (int i = 0; i != X.length; i++)
91         {
92             X[i] = 0;
93         }
94         mOff = 0;\r
95         for (int i = 0; i != M.length; i++)
96         {
97             M[i] = 0;
98         }
99         COff = 0;\r
100         for (int i = 0; i != C.length; i++)
101         {
102             C[i] = 0;
103         }
104     }\r
105     /**\r
106      * update the message digest with a single byte.
107      *
108      * @param in the input byte to be entered.
109      */
110         public void update(byte in)
111     {
112         M[mOff++] = in;
113
114         if (mOff == 16)
115         {
116             processCheckSum(M);
117             processBlock(M);
118             mOff = 0;
119         }
120     }
121
122     /**
123      * update the message digest with a block of bytes.
124      *
125      * @param in the byte array containing the data.
126      * @param inOff the offset into the byte array where the data starts.
127      * @param len the length of the data.
128      */
129         public void update(byte[] in, int inOff, int len)\r
130     {\r
131         //\r
132         // fill the current word
133         //
134         while ((mOff != 0) && (len > 0))
135         {
136             update(in[inOff]);
137             inOff++;
138             len--;
139         }
140
141         //
142         // process whole words.
143         //
144         while (len > 16)
145         {
146             System.arraycopy(in,inOff,M,0,16);
147             processCheckSum(M);
148             processBlock(M);
149             len -= 16;
150             inOff += 16;
151         }
152
153         //
154         // load in the remainder.
155         //
156         while (len > 0)
157         {
158             update(in[inOff]);
159             inOff++;
160             len--;
161         }\r
162     }\r
163     protected void processCheckSum(byte[] m)\r
164     {\r
165         int L = C[15];\r
166         for (int i=0;i<16;i++)\r
167         {\r
168             C[i] ^= S[(m[i] ^ L) & 0xff];\r
169             L = C[i];\r
170         }\r
171     }\r
172     protected void processBlock(byte[] m)\r
173     {
174         for (int i=0;i<16;i++)
175         {
176             X[i+16] = m[i];
177             X[i+32] = (byte)(m[i] ^ X[i]);
178         }
179         // encrypt block
180         int t = 0;
181
182         for (int j=0;j<18;j++)
183         {
184             for (int k=0;k<48;k++)
185             {
186                 t = X[k] ^= S[t];
187                 t = t & 0xff;
188             }
189             t = (t + j)%256;
190         }
191      }
192      // 256-byte random permutation constructed from the digits of PI
193     private static final byte[] S = {\r
194       (byte)41,(byte)46,(byte)67,(byte)201,(byte)162,(byte)216,(byte)124,\r
195       (byte)1,(byte)61,(byte)54,(byte)84,(byte)161,(byte)236,(byte)240,\r
196       (byte)6,(byte)19,(byte)98,(byte)167,(byte)5,(byte)243,(byte)192,\r
197       (byte)199,(byte)115,(byte)140,(byte)152,(byte)147,(byte)43,(byte)217,\r
198       (byte)188,(byte)76,(byte)130,(byte)202,(byte)30,(byte)155,(byte)87,\r
199       (byte)60,(byte)253,(byte)212,(byte)224,(byte)22,(byte)103,(byte)66,\r
200       (byte)111,(byte)24,(byte)138,(byte)23,(byte)229,(byte)18,(byte)190,\r
201       (byte)78,(byte)196,(byte)214,(byte)218,(byte)158,(byte)222,(byte)73,\r
202       (byte)160,(byte)251,(byte)245,(byte)142,(byte)187,(byte)47,(byte)238,\r
203       (byte)122,(byte)169,(byte)104,(byte)121,(byte)145,(byte)21,(byte)178,\r
204       (byte)7,(byte)63,(byte)148,(byte)194,(byte)16,(byte)137,(byte)11,\r
205       (byte)34,(byte)95,(byte)33,(byte)128,(byte)127,(byte)93,(byte)154,\r
206       (byte)90,(byte)144,(byte)50,(byte)39,(byte)53,(byte)62,(byte)204,\r
207       (byte)231,(byte)191,(byte)247,(byte)151,(byte)3,(byte)255,(byte)25,\r
208       (byte)48,(byte)179,(byte)72,(byte)165,(byte)181,(byte)209,(byte)215,\r
209       (byte)94,(byte)146,(byte)42,(byte)172,(byte)86,(byte)170,(byte)198,\r
210       (byte)79,(byte)184,(byte)56,(byte)210,(byte)150,(byte)164,(byte)125,\r
211       (byte)182,(byte)118,(byte)252,(byte)107,(byte)226,(byte)156,(byte)116,\r
212       (byte)4,(byte)241,(byte)69,(byte)157,(byte)112,(byte)89,(byte)100,\r
213       (byte)113,(byte)135,(byte)32,(byte)134,(byte)91,(byte)207,(byte)101,\r
214       (byte)230,(byte)45,(byte)168,(byte)2,(byte)27,(byte)96,(byte)37,\r
215       (byte)173,(byte)174,(byte)176,(byte)185,(byte)246,(byte)28,(byte)70,\r
216       (byte)97,(byte)105,(byte)52,(byte)64,(byte)126,(byte)15,(byte)85,\r
217       (byte)71,(byte)163,(byte)35,(byte)221,(byte)81,(byte)175,(byte)58,\r
218       (byte)195,(byte)92,(byte)249,(byte)206,(byte)186,(byte)197,(byte)234,\r
219       (byte)38,(byte)44,(byte)83,(byte)13,(byte)110,(byte)133,(byte)40,\r
220       (byte)132, 9,(byte)211,(byte)223,(byte)205,(byte)244,(byte)65,\r
221       (byte)129,(byte)77,(byte)82,(byte)106,(byte)220,(byte)55,(byte)200,\r
222       (byte)108,(byte)193,(byte)171,(byte)250,(byte)36,(byte)225,(byte)123,\r
223       (byte)8,(byte)12,(byte)189,(byte)177,(byte)74,(byte)120,(byte)136,\r
224       (byte)149,(byte)139,(byte)227,(byte)99,(byte)232,(byte)109,(byte)233,\r
225       (byte)203,(byte)213,(byte)254,(byte)59,(byte)0,(byte)29,(byte)57,\r
226       (byte)242,(byte)239,(byte)183,(byte)14,(byte)102,(byte)88,(byte)208,\r
227       (byte)228,(byte)166,(byte)119,(byte)114,(byte)248,(byte)235,(byte)117,\r
228       (byte)75,(byte)10,(byte)49,(byte)68,(byte)80,(byte)180,(byte)143,\r
229       (byte)237,(byte)31,(byte)26,(byte)219,(byte)153,(byte)141,(byte)51,\r
230       (byte)159,(byte)17,(byte)131,(byte)20\r
231     };\r
232 }\r