comparison tango/tango/io/digest/Md2.d @ 132:1700239cab2e trunk

[svn r136] MAJOR UNSTABLE UPDATE!!! Initial commit after moving to Tango instead of Phobos. Lots of bugfixes... This build is not suitable for most things.
author lindquist
date Fri, 11 Jan 2008 17:57:40 +0100
parents
children
comparison
equal deleted inserted replaced
131:5825d48b27d1 132:1700239cab2e
1 /*******************************************************************************
2
3 copyright: Copyright (c) 2006 Tango. All rights reserved
4
5 license: BSD style: see doc/license.txt for details
6
7 version: Initial release: Feb 2006
8
9 author: Regan Heath, Oskar Linde
10
11 This module implements the MD2 Message Digest Algorithm as described
12 by RFC 1319 The MD2 Message-Digest Algorithm. B. Kaliski. April 1992.
13
14 *******************************************************************************/
15
16 module tango.io.digest.Md2;
17
18 public import tango.io.digest.Digest;
19
20 private import tango.io.digest.MerkleDamgard;
21
22 /*******************************************************************************
23
24 *******************************************************************************/
25
26 class Md2 : MerkleDamgard
27 {
28 private ubyte[16] C,
29 state;
30
31 /***********************************************************************
32
33 Construct an Md2
34
35 ***********************************************************************/
36
37 this() { }
38
39 /***********************************************************************
40
41 Initialize the cipher
42
43 Remarks:
44 Returns the cipher state to it's initial value
45
46 ***********************************************************************/
47
48 protected override void reset()
49 {
50 super.reset();
51 state[] = 0;
52 C[] = 0;
53 }
54
55 /***********************************************************************
56
57 Obtain the digest
58
59 Returns:
60 the digest
61
62 Remarks:
63 Returns a digest of the current cipher state, this may
64 be the final digest, or a digest of the state between
65 calls to update()
66
67 ***********************************************************************/
68
69 protected override void createDigest(ubyte[] buf)
70 {
71 buf[] = state;
72 }
73
74 /***********************************************************************
75
76 The MD 2 digest size is 16 bytes
77
78 ***********************************************************************/
79
80 uint digestSize() { return 16; }
81
82 /***********************************************************************
83
84 block size
85
86 Returns:
87 the block size
88
89 Remarks:
90 Specifies the size (in bytes) of the block of data to pass to
91 each call to transform(). For MD2 the blockSize is 16.
92
93 ***********************************************************************/
94
95 protected override uint blockSize()
96 {
97 return 16;
98 }
99
100 /***********************************************************************
101
102 Length padding size
103
104 Returns:
105 the length padding size
106
107 Remarks:
108 Specifies the size (in bytes) of the padding which uses the
109 length of the data which has been ciphered, this padding is
110 carried out by the padLength method. For MD2 the addSize is
111 0
112
113 ***********************************************************************/
114
115 protected override uint addSize()
116 {
117 return 0;
118 }
119
120 /***********************************************************************
121
122 Pads the cipher data
123
124 Params:
125 data = a slice of the cipher buffer to fill with padding
126
127 Remarks:
128 Fills the passed buffer slice with the appropriate padding
129 for the final call to transform(). This padding will fill
130 the cipher buffer up to blockSize()-addSize().
131
132 ***********************************************************************/
133
134 protected override void padMessage (ubyte[] data)
135 {
136 /* Padding is performed as follows: "i" bytes of value "i"
137 * are appended to the message so that the length in bytes
138 * of the padded message becomes congruent to 0, modulo 16.
139 * At least one byte and at most 16 bytes are appended.
140 */
141 data[0..$] = cast(ubyte) data.length;
142 }
143
144 /***********************************************************************
145
146 Performs the cipher on a block of data
147
148 Params:
149 data = the block of data to cipher
150
151 Remarks:
152 The actual cipher algorithm is carried out by this method on
153 the passed block of data. This method is called for every
154 blockSize() bytes of input data and once more with the
155 remaining data padded to blockSize().
156
157 ***********************************************************************/
158
159 protected override void transform (ubyte[] input)
160 {
161 ubyte[48] X;
162 uint t,i,j;
163
164 X[0..16] = state[];
165 X[16..32] = input[];
166
167 for (i = 0; i < 16; i++)
168 X[i+32] = cast(ubyte) (state[i] ^ input[i]);
169
170 t = 0;
171 for (i = 0; i < 18; i++)
172 {
173 for (j = 0; j < 48; j++)
174 t = X[j] ^= PI[t];
175 t = (t + i) & 0xff;
176 }
177
178 state[] = X[0..16];
179
180 t = C[15];
181
182 for (i = 0; i < 16; i++)
183 t = C[i] ^= PI[input[i] ^ t];
184 }
185
186 /***********************************************************************
187
188 Final processing of cipher.
189
190 Remarks:
191 This method is called after the final transform just prior to
192 the creation of the final digest. The MD2 algorithm requires
193 an additional step at this stage. Future ciphers may or may not
194 require this method.
195
196 ***********************************************************************/
197
198 protected override void extend()
199 {
200 transform(C);
201 }
202 }
203
204
205 /*******************************************************************************
206
207 *******************************************************************************/
208
209 private const ubyte[256] PI =
210 [
211 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
212 19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
213 76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
214 138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
215 245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
216 148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
217 39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
218 181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
219 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
220 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
221 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
222 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
223 234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
224 129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
225 8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
226 203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
227 166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
228 31, 26, 219, 153, 141, 51, 159, 17, 131, 20
229 ];
230
231
232 /*******************************************************************************
233
234 *******************************************************************************/
235
236 version (UnitTest)
237 {
238 unittest
239 {
240 static char[][] strings =
241 [
242 "",
243 "a",
244 "abc",
245 "message digest",
246 "abcdefghijklmnopqrstuvwxyz",
247 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
248 "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
249 ];
250
251 static char[][] results =
252 [
253 "8350e5a3e24c153df2275c9f80692773",
254 "32ec01ec4a6dac72c0ab96fb34c0b5d1",
255 "da853b0d3f88d99b30283a69e6ded6bb",
256 "ab4f496bfb2a530b219ff33031fe06b0",
257 "4e8ddff3650292ab5a4108c3aa47940b",
258 "da33def2a42df13975352846c30338cd",
259 "d5976f79d83d3a0dc9806c3c66f3efd8"
260 ];
261
262 Md2 h = new Md2();
263
264 foreach (int i, char[] s; strings)
265 {
266 h.update(s);
267 char[] d = h.hexDigest();
268 assert(d == results[i],":("~s~")("~d~")!=("~results[i]~")");
269 }
270 }
271 }
272