1 /* $FreeBSD: src/sys/crypto/md5.h,v 1.4 2002/03/20 05:13:50 alfred Exp $ */
2 /* $KAME: md5.h,v 1.4 2000/03/27 04:36:22 sumikawa Exp $ */
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the project nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 #ifndef _NETINET6_MD5_H_
36 #define _NETINET6_MD5_H_
40 typedef long unsigned int u_int32_t;
41 typedef long long unsigned int u_int64_t;
42 typedef unsigned char u_int8_t;
43 typedef unsigned int u_int;
44 typedef unsigned long u_long;
45 typedef unsigned char u_char;
49 u_int32_t md5_state32[4];
50 u_int8_t md5_state8[16];
53 #define md5_sta md5_st.md5_state32[0]
54 #define md5_stb md5_st.md5_state32[1]
55 #define md5_stc md5_st.md5_state32[2]
56 #define md5_std md5_st.md5_state32[3]
57 #define md5_st8 md5_st.md5_state8
60 u_int64_t md5_count64;
61 u_int8_t md5_count8[8];
63 #define md5_n md5_count.md5_count64
64 #define md5_n8 md5_count.md5_count8
67 u_int8_t md5_buf[MD5_BUFLEN];
70 static void md5_init(md5_ctxt *);
71 static void md5_loop(md5_ctxt *, const u_int8_t *, u_int);
72 static void md5_pad(md5_ctxt *);
73 static void md5_result(u_int8_t *, md5_ctxt *);
76 #define MD5_CTX md5_ctxt
77 #define MD5Init(x) md5_init((x))
78 #define MD5Update(x, y, z) md5_loop((x), (y), (z))
79 #define MD5Final(x, y) \
82 md5_result((x), (y)); \
85 #endif /* ! _NETINET6_MD5_H_*/
88 * Copyright (c) 2003 Poul-Henning Kamp
90 * University of California. All rights reserved.
91 * All rights reserved.
93 * Redistribution and use in source and binary forms, with or without
94 * modification, are permitted provided that the following conditions
96 * 1. Redistributions of source code must retain the above copyright
97 * notice, this list of conditions and the following disclaimer.
98 * 2. Redistributions in binary form must reproduce the above copyright
99 * notice, this list of conditions and the following disclaimer in the
100 * documentation and/or other materials provided with the distribution.
101 * 3. Neither the name of the author nor the names of any co-contributors
102 * may be used to endorse or promote products derived from this software
103 * without specific prior written permission.
105 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
106 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
107 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
108 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
109 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
110 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
111 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
112 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
113 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
114 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
124 void bcopy(void*src, void*dest, int len)
126 memcpy(dest, src, len);
131 void bzero(void*mem, int len)
140 static char itoa64[] = /* 0 ... 63 => ascii - 64 */
141 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
144 _crypt_to64(char *s, u_long v, int n)
147 *s++ = itoa64[v&0x3f];
152 char * crypt_md5(const char *pw, const char *salt)
158 u_char final[MD5_SIZE];
159 static const char *sp, *ep;
160 static char passwd[120], *p;
161 static const char *magic = "$1$";
163 /* Refine the Salt first */
166 /* If it starts with the magic string, then skip that */
167 if(!strncmp(sp, magic, strlen(magic)))
170 /* It stops at the first '$', max 8 chars */
171 for(ep = sp; *ep && *ep != '$' && ep < (sp + 8); ep++)
174 /* get the length of the true salt */
179 /* The password first, since that is what is most unknown */
180 MD5Update(&ctx, (const u_char *)pw, strlen(pw));
182 /* Then our magic string */
183 MD5Update(&ctx, (const u_char *)magic, strlen(magic));
185 /* Then the raw salt */
186 MD5Update(&ctx, (const u_char *)sp, (u_int)sl);
188 /* Then just as many characters of the MD5(pw,salt,pw) */
190 MD5Update(&ctx1, (const u_char *)pw, strlen(pw));
191 MD5Update(&ctx1, (const u_char *)sp, (u_int)sl);
192 MD5Update(&ctx1, (const u_char *)pw, strlen(pw));
193 MD5Final(final, &ctx1);
194 for(pl = (int)strlen(pw); pl > 0; pl -= MD5_SIZE)
195 MD5Update(&ctx, (const u_char *)final,
196 (u_int)(pl > MD5_SIZE ? MD5_SIZE : pl));
198 /* Don't leave anything around in vm they could use. */
199 memset(final, 0, sizeof(final));
201 /* Then something really weird... */
202 for (i = strlen(pw); i; i >>= 1)
204 MD5Update(&ctx, (const u_char *)final, 1);
206 MD5Update(&ctx, (const u_char *)pw, 1);
208 /* Now make the output string */
209 strcpy(passwd, magic);
210 strncat(passwd, sp, (u_int)sl);
213 MD5Final(final, &ctx);
216 * and now, just to make sure things don't run too fast
217 * On a 60 Mhz Pentium this takes 34 msec, so you would
218 * need 30 seconds to build a 1000 entry dictionary...
220 for(i = 0; i < 1000; i++) {
223 MD5Update(&ctx1, (const u_char *)pw, strlen(pw));
225 MD5Update(&ctx1, (const u_char *)final, MD5_SIZE);
228 MD5Update(&ctx1, (const u_char *)sp, (u_int)sl);
231 MD5Update(&ctx1, (const u_char *)pw, strlen(pw));
234 MD5Update(&ctx1, (const u_char *)final, MD5_SIZE);
236 MD5Update(&ctx1, (const u_char *)pw, strlen(pw));
237 MD5Final(final, &ctx1);
240 p = passwd + strlen(passwd);
242 l = (final[ 0]<<16) | (final[ 6]<<8) | final[12];
243 _crypt_to64(p, l, 4); p += 4;
244 l = (final[ 1]<<16) | (final[ 7]<<8) | final[13];
245 _crypt_to64(p, l, 4); p += 4;
246 l = (final[ 2]<<16) | (final[ 8]<<8) | final[14];
247 _crypt_to64(p, l, 4); p += 4;
248 l = (final[ 3]<<16) | (final[ 9]<<8) | final[15];
249 _crypt_to64(p, l, 4); p += 4;
250 l = (final[ 4]<<16) | (final[10]<<8) | final[ 5];
251 _crypt_to64(p, l, 4); p += 4;
253 _crypt_to64(p, l, 2); p += 2;
256 /* Don't leave anything around in vm they could use. */
257 memset(final, 0, sizeof(final));
262 /* $KAME: md5.c,v 1.5 2000/11/08 06:13:08 itojun Exp $ */
264 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
265 * All rights reserved.
267 * Redistribution and use in source and binary forms, with or without
268 * modification, are permitted provided that the following conditions
270 * 1. Redistributions of source code must retain the above copyright
271 * notice, this list of conditions and the following disclaimer.
272 * 2. Redistributions in binary form must reproduce the above copyright
273 * notice, this list of conditions and the following disclaimer in the
274 * documentation and/or other materials provided with the distribution.
275 * 3. Neither the name of the project nor the names of its contributors
276 * may be used to endorse or promote products derived from this software
277 * without specific prior written permission.
279 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
280 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
281 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
282 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
283 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
284 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
285 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
286 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
287 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
288 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
292 #define SHIFT(X, s) (((X) << (s)) | ((X) >> (32 - (s))))
294 #define F(X, Y, Z) (((X) & (Y)) | ((~X) & (Z)))
295 #define G(X, Y, Z) (((X) & (Z)) | ((Y) & (~Z)))
296 #define H(X, Y, Z) ((X) ^ (Y) ^ (Z))
297 #define I(X, Y, Z) ((Y) ^ ((X) | (~Z)))
299 #define ROUND1(a, b, c, d, k, s, i) { \
300 (a) = (a) + F((b), (c), (d)) + X[(k)] + T[(i)]; \
301 (a) = SHIFT((a), (s)); \
305 #define ROUND2(a, b, c, d, k, s, i) { \
306 (a) = (a) + G((b), (c), (d)) + X[(k)] + T[(i)]; \
307 (a) = SHIFT((a), (s)); \
311 #define ROUND3(a, b, c, d, k, s, i) { \
312 (a) = (a) + H((b), (c), (d)) + X[(k)] + T[(i)]; \
313 (a) = SHIFT((a), (s)); \
317 #define ROUND4(a, b, c, d, k, s, i) { \
318 (a) = (a) + I((b), (c), (d)) + X[(k)] + T[(i)]; \
319 (a) = SHIFT((a), (s)); \
343 #define MD5_A0 0x67452301
344 #define MD5_B0 0xefcdab89
345 #define MD5_C0 0x98badcfe
346 #define MD5_D0 0x10325476
348 /* Integer part of 4294967296 times abs(sin(i)), where i is in radians. */
349 static const u_int32_t T[65] = {
351 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
352 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
353 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
354 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
356 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
357 0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8,
358 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
359 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
361 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
362 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
363 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05,
364 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
366 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
367 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
368 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
369 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
372 static const u_int8_t md5_paddat[MD5_BUFLEN] = {
373 0x80, 0, 0, 0, 0, 0, 0, 0,
374 0, 0, 0, 0, 0, 0, 0, 0,
375 0, 0, 0, 0, 0, 0, 0, 0,
376 0, 0, 0, 0, 0, 0, 0, 0,
377 0, 0, 0, 0, 0, 0, 0, 0,
378 0, 0, 0, 0, 0, 0, 0, 0,
379 0, 0, 0, 0, 0, 0, 0, 0,
380 0, 0, 0, 0, 0, 0, 0, 0,
383 static void md5_calc(u_int8_t *, md5_ctxt *);
385 static void md5_init(ctxt)
390 ctxt->md5_sta = MD5_A0;
391 ctxt->md5_stb = MD5_B0;
392 ctxt->md5_stc = MD5_C0;
393 ctxt->md5_std = MD5_D0;
394 bzero(ctxt->md5_buf, sizeof(ctxt->md5_buf));
397 static void md5_loop(ctxt, input, len)
399 const u_int8_t *input;
400 u_int len; /* number of bytes */
404 ctxt->md5_n += len * 8; /* byte to bit */
405 gap = MD5_BUFLEN - ctxt->md5_i;
408 bcopy((void *)input, (void *)(ctxt->md5_buf + ctxt->md5_i),
410 md5_calc(ctxt->md5_buf, ctxt);
412 for (i = gap; i + MD5_BUFLEN <= len; i += MD5_BUFLEN) {
413 md5_calc((u_int8_t *)(input + i), ctxt);
416 ctxt->md5_i = len - i;
417 bcopy((void *)(input + i), (void *)ctxt->md5_buf, ctxt->md5_i);
419 bcopy((void *)input, (void *)(ctxt->md5_buf + ctxt->md5_i),
425 static void md5_pad(ctxt)
430 /* Don't count up padding. Keep md5_n. */
431 gap = MD5_BUFLEN - ctxt->md5_i;
434 (void *)(ctxt->md5_buf + ctxt->md5_i),
435 gap - sizeof(ctxt->md5_n));
437 /* including gap == 8 */
438 bcopy(md5_paddat, (void *)(ctxt->md5_buf + ctxt->md5_i),
440 md5_calc(ctxt->md5_buf, ctxt);
441 bcopy((md5_paddat + gap),
442 (void *)ctxt->md5_buf,
443 MD5_BUFLEN - sizeof(ctxt->md5_n));
447 #if BYTE_ORDER == LITTLE_ENDIAN
448 bcopy(&ctxt->md5_n8[0], &ctxt->md5_buf[56], 8);
450 #if BYTE_ORDER == BIG_ENDIAN
451 ctxt->md5_buf[56] = ctxt->md5_n8[7];
452 ctxt->md5_buf[57] = ctxt->md5_n8[6];
453 ctxt->md5_buf[58] = ctxt->md5_n8[5];
454 ctxt->md5_buf[59] = ctxt->md5_n8[4];
455 ctxt->md5_buf[60] = ctxt->md5_n8[3];
456 ctxt->md5_buf[61] = ctxt->md5_n8[2];
457 ctxt->md5_buf[62] = ctxt->md5_n8[1];
458 ctxt->md5_buf[63] = ctxt->md5_n8[0];
461 md5_calc(ctxt->md5_buf, ctxt);
464 static void md5_result(digest, ctxt)
469 #if BYTE_ORDER == LITTLE_ENDIAN
470 bcopy(&ctxt->md5_st8[0], digest, 16);
472 #if BYTE_ORDER == BIG_ENDIAN
473 digest[ 0] = ctxt->md5_st8[ 3]; digest[ 1] = ctxt->md5_st8[ 2];
474 digest[ 2] = ctxt->md5_st8[ 1]; digest[ 3] = ctxt->md5_st8[ 0];
475 digest[ 4] = ctxt->md5_st8[ 7]; digest[ 5] = ctxt->md5_st8[ 6];
476 digest[ 6] = ctxt->md5_st8[ 5]; digest[ 7] = ctxt->md5_st8[ 4];
477 digest[ 8] = ctxt->md5_st8[11]; digest[ 9] = ctxt->md5_st8[10];
478 digest[10] = ctxt->md5_st8[ 9]; digest[11] = ctxt->md5_st8[ 8];
479 digest[12] = ctxt->md5_st8[15]; digest[13] = ctxt->md5_st8[14];
480 digest[14] = ctxt->md5_st8[13]; digest[15] = ctxt->md5_st8[12];
484 #if BYTE_ORDER == BIG_ENDIAN
488 static void md5_calc(b64, ctxt)
492 u_int32_t A = ctxt->md5_sta;
493 u_int32_t B = ctxt->md5_stb;
494 u_int32_t C = ctxt->md5_stc;
495 u_int32_t D = ctxt->md5_std;
496 #if BYTE_ORDER == LITTLE_ENDIAN
497 u_int32_t *X = (u_int32_t *)b64;
499 #if BYTE_ORDER == BIG_ENDIAN
501 /* what a brute force but fast! */
502 u_int8_t *y = (u_int8_t *)X;
503 y[ 0] = b64[ 3]; y[ 1] = b64[ 2]; y[ 2] = b64[ 1]; y[ 3] = b64[ 0];
504 y[ 4] = b64[ 7]; y[ 5] = b64[ 6]; y[ 6] = b64[ 5]; y[ 7] = b64[ 4];
505 y[ 8] = b64[11]; y[ 9] = b64[10]; y[10] = b64[ 9]; y[11] = b64[ 8];
506 y[12] = b64[15]; y[13] = b64[14]; y[14] = b64[13]; y[15] = b64[12];
507 y[16] = b64[19]; y[17] = b64[18]; y[18] = b64[17]; y[19] = b64[16];
508 y[20] = b64[23]; y[21] = b64[22]; y[22] = b64[21]; y[23] = b64[20];
509 y[24] = b64[27]; y[25] = b64[26]; y[26] = b64[25]; y[27] = b64[24];
510 y[28] = b64[31]; y[29] = b64[30]; y[30] = b64[29]; y[31] = b64[28];
511 y[32] = b64[35]; y[33] = b64[34]; y[34] = b64[33]; y[35] = b64[32];
512 y[36] = b64[39]; y[37] = b64[38]; y[38] = b64[37]; y[39] = b64[36];
513 y[40] = b64[43]; y[41] = b64[42]; y[42] = b64[41]; y[43] = b64[40];
514 y[44] = b64[47]; y[45] = b64[46]; y[46] = b64[45]; y[47] = b64[44];
515 y[48] = b64[51]; y[49] = b64[50]; y[50] = b64[49]; y[51] = b64[48];
516 y[52] = b64[55]; y[53] = b64[54]; y[54] = b64[53]; y[55] = b64[52];
517 y[56] = b64[59]; y[57] = b64[58]; y[58] = b64[57]; y[59] = b64[56];
518 y[60] = b64[63]; y[61] = b64[62]; y[62] = b64[61]; y[63] = b64[60];
521 ROUND1(A, B, C, D, 0, Sa, 1); ROUND1(D, A, B, C, 1, Sb, 2);
522 ROUND1(C, D, A, B, 2, Sc, 3); ROUND1(B, C, D, A, 3, Sd, 4);
523 ROUND1(A, B, C, D, 4, Sa, 5); ROUND1(D, A, B, C, 5, Sb, 6);
524 ROUND1(C, D, A, B, 6, Sc, 7); ROUND1(B, C, D, A, 7, Sd, 8);
525 ROUND1(A, B, C, D, 8, Sa, 9); ROUND1(D, A, B, C, 9, Sb, 10);
526 ROUND1(C, D, A, B, 10, Sc, 11); ROUND1(B, C, D, A, 11, Sd, 12);
527 ROUND1(A, B, C, D, 12, Sa, 13); ROUND1(D, A, B, C, 13, Sb, 14);
528 ROUND1(C, D, A, B, 14, Sc, 15); ROUND1(B, C, D, A, 15, Sd, 16);
530 ROUND2(A, B, C, D, 1, Se, 17); ROUND2(D, A, B, C, 6, Sf, 18);
531 ROUND2(C, D, A, B, 11, Sg, 19); ROUND2(B, C, D, A, 0, Sh, 20);
532 ROUND2(A, B, C, D, 5, Se, 21); ROUND2(D, A, B, C, 10, Sf, 22);
533 ROUND2(C, D, A, B, 15, Sg, 23); ROUND2(B, C, D, A, 4, Sh, 24);
534 ROUND2(A, B, C, D, 9, Se, 25); ROUND2(D, A, B, C, 14, Sf, 26);
535 ROUND2(C, D, A, B, 3, Sg, 27); ROUND2(B, C, D, A, 8, Sh, 28);
536 ROUND2(A, B, C, D, 13, Se, 29); ROUND2(D, A, B, C, 2, Sf, 30);
537 ROUND2(C, D, A, B, 7, Sg, 31); ROUND2(B, C, D, A, 12, Sh, 32);
539 ROUND3(A, B, C, D, 5, Si, 33); ROUND3(D, A, B, C, 8, Sj, 34);
540 ROUND3(C, D, A, B, 11, Sk, 35); ROUND3(B, C, D, A, 14, Sl, 36);
541 ROUND3(A, B, C, D, 1, Si, 37); ROUND3(D, A, B, C, 4, Sj, 38);
542 ROUND3(C, D, A, B, 7, Sk, 39); ROUND3(B, C, D, A, 10, Sl, 40);
543 ROUND3(A, B, C, D, 13, Si, 41); ROUND3(D, A, B, C, 0, Sj, 42);
544 ROUND3(C, D, A, B, 3, Sk, 43); ROUND3(B, C, D, A, 6, Sl, 44);
545 ROUND3(A, B, C, D, 9, Si, 45); ROUND3(D, A, B, C, 12, Sj, 46);
546 ROUND3(C, D, A, B, 15, Sk, 47); ROUND3(B, C, D, A, 2, Sl, 48);
548 ROUND4(A, B, C, D, 0, Sm, 49); ROUND4(D, A, B, C, 7, Sn, 50);
549 ROUND4(C, D, A, B, 14, So, 51); ROUND4(B, C, D, A, 5, Sp, 52);
550 ROUND4(A, B, C, D, 12, Sm, 53); ROUND4(D, A, B, C, 3, Sn, 54);
551 ROUND4(C, D, A, B, 10, So, 55); ROUND4(B, C, D, A, 1, Sp, 56);
552 ROUND4(A, B, C, D, 8, Sm, 57); ROUND4(D, A, B, C, 15, Sn, 58);
553 ROUND4(C, D, A, B, 6, So, 59); ROUND4(B, C, D, A, 13, Sp, 60);
554 ROUND4(A, B, C, D, 4, Sm, 61); ROUND4(D, A, B, C, 11, Sn, 62);
555 ROUND4(C, D, A, B, 2, So, 63); ROUND4(B, C, D, A, 9, Sp, 64);