Mercurial > projects > ldc
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 |