2 atlc - arbitrary transmission line calculator, for the analysis of
3 transmission lines are directional couplers.
5 Copyright (C) 2002. Dr. David Kirkby, PhD (G8WRB).
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either package_version 2
10 of the License, or (at your option) any later package_version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
22 Dr. David Kirkby, e-mail drkirkby@ntlworld.com
28 * RFC 1321 compliant MD5 implementation,
29 * by Christophe Devine <devine@cr0.net>;
30 * this program is licensed under the GPL.
37 #define GET_UINT32(n,b,i) \
39 (n) = (uint32) ((uint8 *) b)[(i)] \
40 | (((uint32) ((uint8 *) b)[(i)+1]) << 8) \
41 | (((uint32) ((uint8 *) b)[(i)+2]) << 16) \
42 | (((uint32) ((uint8 *) b)[(i)+3]) << 24); \
45 #define PUT_UINT32(n,b,i) \
47 (((uint8 *) b)[(i)] ) = (uint8) (((n) ) & 0xFF); \
48 (((uint8 *) b)[(i)+1]) = (uint8) (((n) >> 8) & 0xFF); \
49 (((uint8 *) b)[(i)+2]) = (uint8) (((n) >> 16) & 0xFF); \
50 (((uint8 *) b)[(i)+3]) = (uint8) (((n) >> 24) & 0xFF); \
53 void md5_starts( struct md5_context *ctx )
57 ctx->state[0] = 0x67452301;
58 ctx->state[1] = 0xEFCDAB89;
59 ctx->state[2] = 0x98BADCFE;
60 ctx->state[3] = 0x10325476;
63 void md5_process( struct md5_context *ctx, uint8 data[64] )
65 uint32 A, B, C, D, X[16];
67 GET_UINT32( X[0], data, 0 );
68 GET_UINT32( X[1], data, 4 );
69 GET_UINT32( X[2], data, 8 );
70 GET_UINT32( X[3], data, 12 );
71 GET_UINT32( X[4], data, 16 );
72 GET_UINT32( X[5], data, 20 );
73 GET_UINT32( X[6], data, 24 );
74 GET_UINT32( X[7], data, 28 );
75 GET_UINT32( X[8], data, 32 );
76 GET_UINT32( X[9], data, 36 );
77 GET_UINT32( X[10], data, 40 );
78 GET_UINT32( X[11], data, 44 );
79 GET_UINT32( X[12], data, 48 );
80 GET_UINT32( X[13], data, 52 );
81 GET_UINT32( X[14], data, 56 );
82 GET_UINT32( X[15], data, 60 );
84 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
86 #define P(a,b,c,d,k,s,t) \
88 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
96 #define F(x,y,z) (z ^ (x & (y ^ z)))
98 P( A, B, C, D, 0, 7, 0xD76AA478 );
99 P( D, A, B, C, 1, 12, 0xE8C7B756 );
100 P( C, D, A, B, 2, 17, 0x242070DB );
101 P( B, C, D, A, 3, 22, 0xC1BDCEEE );
102 P( A, B, C, D, 4, 7, 0xF57C0FAF );
103 P( D, A, B, C, 5, 12, 0x4787C62A );
104 P( C, D, A, B, 6, 17, 0xA8304613 );
105 P( B, C, D, A, 7, 22, 0xFD469501 );
106 P( A, B, C, D, 8, 7, 0x698098D8 );
107 P( D, A, B, C, 9, 12, 0x8B44F7AF );
108 P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
109 P( B, C, D, A, 11, 22, 0x895CD7BE );
110 P( A, B, C, D, 12, 7, 0x6B901122 );
111 P( D, A, B, C, 13, 12, 0xFD987193 );
112 P( C, D, A, B, 14, 17, 0xA679438E );
113 P( B, C, D, A, 15, 22, 0x49B40821 );
117 #define F(x,y,z) (y ^ (z & (x ^ y)))
119 P( A, B, C, D, 1, 5, 0xF61E2562 );
120 P( D, A, B, C, 6, 9, 0xC040B340 );
121 P( C, D, A, B, 11, 14, 0x265E5A51 );
122 P( B, C, D, A, 0, 20, 0xE9B6C7AA );
123 P( A, B, C, D, 5, 5, 0xD62F105D );
124 P( D, A, B, C, 10, 9, 0x02441453 );
125 P( C, D, A, B, 15, 14, 0xD8A1E681 );
126 P( B, C, D, A, 4, 20, 0xE7D3FBC8 );
127 P( A, B, C, D, 9, 5, 0x21E1CDE6 );
128 P( D, A, B, C, 14, 9, 0xC33707D6 );
129 P( C, D, A, B, 3, 14, 0xF4D50D87 );
130 P( B, C, D, A, 8, 20, 0x455A14ED );
131 P( A, B, C, D, 13, 5, 0xA9E3E905 );
132 P( D, A, B, C, 2, 9, 0xFCEFA3F8 );
133 P( C, D, A, B, 7, 14, 0x676F02D9 );
134 P( B, C, D, A, 12, 20, 0x8D2A4C8A );
138 #define F(x,y,z) (x ^ y ^ z)
140 P( A, B, C, D, 5, 4, 0xFFFA3942 );
141 P( D, A, B, C, 8, 11, 0x8771F681 );
142 P( C, D, A, B, 11, 16, 0x6D9D6122 );
143 P( B, C, D, A, 14, 23, 0xFDE5380C );
144 P( A, B, C, D, 1, 4, 0xA4BEEA44 );
145 P( D, A, B, C, 4, 11, 0x4BDECFA9 );
146 P( C, D, A, B, 7, 16, 0xF6BB4B60 );
147 P( B, C, D, A, 10, 23, 0xBEBFBC70 );
148 P( A, B, C, D, 13, 4, 0x289B7EC6 );
149 P( D, A, B, C, 0, 11, 0xEAA127FA );
150 P( C, D, A, B, 3, 16, 0xD4EF3085 );
151 P( B, C, D, A, 6, 23, 0x04881D05 );
152 P( A, B, C, D, 9, 4, 0xD9D4D039 );
153 P( D, A, B, C, 12, 11, 0xE6DB99E5 );
154 P( C, D, A, B, 15, 16, 0x1FA27CF8 );
155 P( B, C, D, A, 2, 23, 0xC4AC5665 );
159 #define F(x,y,z) (y ^ (x | ~z))
161 P( A, B, C, D, 0, 6, 0xF4292244 );
162 P( D, A, B, C, 7, 10, 0x432AFF97 );
163 P( C, D, A, B, 14, 15, 0xAB9423A7 );
164 P( B, C, D, A, 5, 21, 0xFC93A039 );
165 P( A, B, C, D, 12, 6, 0x655B59C3 );
166 P( D, A, B, C, 3, 10, 0x8F0CCC92 );
167 P( C, D, A, B, 10, 15, 0xFFEFF47D );
168 P( B, C, D, A, 1, 21, 0x85845DD1 );
169 P( A, B, C, D, 8, 6, 0x6FA87E4F );
170 P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
171 P( C, D, A, B, 6, 15, 0xA3014314 );
172 P( B, C, D, A, 13, 21, 0x4E0811A1 );
173 P( A, B, C, D, 4, 6, 0xF7537E82 );
174 P( D, A, B, C, 11, 10, 0xBD3AF235 );
175 P( C, D, A, B, 2, 15, 0x2AD7D2BB );
176 P( B, C, D, A, 9, 21, 0xEB86D391 );
186 void md5_update( struct md5_context *ctx, uint8 *input, uint32 length )
190 if( ! length ) return;
192 left = ( ctx->total[0] >> 3 ) & 0x3F;
195 ctx->total[0] += length << 3;
196 ctx->total[1] += length >> 29;
198 ctx->total[0] &= 0xFFFFFFFF;
199 ctx->total[1] += ctx->total[0] < length << 3;
201 if( left && length >= fill )
203 memcpy( (void *) (ctx->buffer + left), (void *) input, fill );
204 md5_process( ctx, ctx->buffer );
210 while( length >= 64 )
212 md5_process( ctx, input );
219 memcpy( (void *) (ctx->buffer + left), (void *) input, length );
223 static uint8 md5_padding[64] =
225 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
226 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
227 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
228 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
231 void md5_finish( struct md5_context *ctx, uint8 digest[16] )
236 PUT_UINT32( ctx->total[0], msglen, 0 );
237 PUT_UINT32( ctx->total[1], msglen, 4 );
239 last = ( ctx->total[0] >> 3 ) & 0x3F;
240 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
242 md5_update( ctx, md5_padding, padn );
243 md5_update( ctx, msglen, 8 );
245 PUT_UINT32( ctx->state[0], digest, 0 );
246 PUT_UINT32( ctx->state[1], digest, 4 );
247 PUT_UINT32( ctx->state[2], digest, 8 );
248 PUT_UINT32( ctx->state[3], digest, 12 );
256 * those are the standard RFC 1321 test vectors
265 "abcdefghijklmnopqrstuvwxyz",
266 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
267 "12345678901234567890123456789012345678901234567890123456789012" \
273 "d41d8cd98f00b204e9800998ecf8427e",
274 "0cc175b9c0f1b6a831c399e269772661",
275 "900150983cd24fb0d6963f7d28e17f72",
276 "f96b697d7cb7938d525a2f31aaf161d0",
277 "c3fcd3d76192e4007dfb496cca67e13b",
278 "d174ab98d277d9f5a5611c2c9f419d9f",
279 "57edf4a22be3c955ac49da2e2107b67a"
282 int main( int argc, char *argv[] )
287 struct md5_context ctx;
288 unsigned char md5sum[16], buffer[1000];
292 for( i = 0; i < 7; i++ )
295 md5_update( &ctx, (uint8 *) msg[i], strlen( msg[i] ) );
296 md5_finish( &ctx, md5sum );
298 for( j = 0; j < 16; j++ )
300 sprintf( output + j * 2, "%02x", md5sum[j] );
303 printf( "test %d ", i + 1 );
305 if( ! memcmp( output, val[i], 32 ) )
307 printf( "passed\n" );
311 printf( "failed\n" );
318 if( ! ( f = fopen( argv[1], "rb" ) ) )
326 while( ( i = fread( buffer, 1, sizeof( buffer ), f ) ) > 0 )
328 md5_update( &ctx, buffer, i );
331 md5_finish( &ctx, md5sum );
333 for( j = 0; j < 16; j++ )
335 printf( "%02x", md5sum[j] );
338 /* printf( " %s\n", argv[1] ); */