3 The compression function for the md5 hash function.
5 Copyright (C) 2001, 2005 Niels Möller
7 This file is part of GNU Nettle.
9 GNU Nettle is free software: you can redistribute it and/or
10 modify it under the terms of either:
12 * the GNU Lesser General Public License as published by the Free
13 Software Foundation; either version 3 of the License, or (at your
14 option) any later version.
18 * the GNU General Public License as published by the Free
19 Software Foundation; either version 2 of the License, or (at your
20 option) any later version.
22 or both in parallel, as here.
24 GNU Nettle is distributed in the hope that it will be useful,
25 but WITHOUT ANY WARRANTY; without even the implied warranty of
26 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27 General Public License for more details.
29 You should have received copies of the GNU General Public License and
30 the GNU Lesser General Public License along with this program. If
31 not, see http://www.gnu.org/licenses/.
34 /* Based on public domain code hacked by Colin Plumb, Andrew Kuchling, and
49 fprintf(stderr, "%2d: %8x %8x %8x %8x\n", i, a, b, c, d)
62 /* A block, treated as a sequence of 32-bit words. */
63 #define MD5_DATA_LENGTH 16
67 #define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
68 #define F2(x, y, z) F1((z), (x), (y))
69 #define F3(x, y, z) ((x) ^ (y) ^ (z))
70 #define F4(x, y, z) ((y) ^ ((x) | ~(z)))
72 #define ROUND(f, w, x, y, z, data, s) \
73 ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
75 /* Perform the MD5 transformation on one full block of 16 32-bit
78 * Compresses 20 (_MD5_DIGEST_LENGTH + MD5_DATA_LENGTH) words into 4
79 * (_MD5_DIGEST_LENGTH) words. */
82 nettle_md5_compress(uint32_t *digest, const uint8_t *input)
84 uint32_t data[MD5_DATA_LENGTH];
88 for (i = 0; i < MD5_DATA_LENGTH; i++, input += 4)
89 data[i] = LE_READ_UINT32(input);
97 ROUND(F1, a, b, c, d, data[ 0] + 0xd76aa478, 7); DEBUG(0);
98 ROUND(F1, d, a, b, c, data[ 1] + 0xe8c7b756, 12); DEBUG(1);
99 ROUND(F1, c, d, a, b, data[ 2] + 0x242070db, 17);
100 ROUND(F1, b, c, d, a, data[ 3] + 0xc1bdceee, 22);
101 ROUND(F1, a, b, c, d, data[ 4] + 0xf57c0faf, 7);
102 ROUND(F1, d, a, b, c, data[ 5] + 0x4787c62a, 12);
103 ROUND(F1, c, d, a, b, data[ 6] + 0xa8304613, 17);
104 ROUND(F1, b, c, d, a, data[ 7] + 0xfd469501, 22);
105 ROUND(F1, a, b, c, d, data[ 8] + 0x698098d8, 7);
106 ROUND(F1, d, a, b, c, data[ 9] + 0x8b44f7af, 12);
107 ROUND(F1, c, d, a, b, data[10] + 0xffff5bb1, 17);
108 ROUND(F1, b, c, d, a, data[11] + 0x895cd7be, 22);
109 ROUND(F1, a, b, c, d, data[12] + 0x6b901122, 7);
110 ROUND(F1, d, a, b, c, data[13] + 0xfd987193, 12);
111 ROUND(F1, c, d, a, b, data[14] + 0xa679438e, 17);
112 ROUND(F1, b, c, d, a, data[15] + 0x49b40821, 22); DEBUG(15);
114 ROUND(F2, a, b, c, d, data[ 1] + 0xf61e2562, 5); DEBUG(16);
115 ROUND(F2, d, a, b, c, data[ 6] + 0xc040b340, 9); DEBUG(17);
116 ROUND(F2, c, d, a, b, data[11] + 0x265e5a51, 14);
117 ROUND(F2, b, c, d, a, data[ 0] + 0xe9b6c7aa, 20);
118 ROUND(F2, a, b, c, d, data[ 5] + 0xd62f105d, 5);
119 ROUND(F2, d, a, b, c, data[10] + 0x02441453, 9);
120 ROUND(F2, c, d, a, b, data[15] + 0xd8a1e681, 14);
121 ROUND(F2, b, c, d, a, data[ 4] + 0xe7d3fbc8, 20);
122 ROUND(F2, a, b, c, d, data[ 9] + 0x21e1cde6, 5);
123 ROUND(F2, d, a, b, c, data[14] + 0xc33707d6, 9);
124 ROUND(F2, c, d, a, b, data[ 3] + 0xf4d50d87, 14);
125 ROUND(F2, b, c, d, a, data[ 8] + 0x455a14ed, 20);
126 ROUND(F2, a, b, c, d, data[13] + 0xa9e3e905, 5);
127 ROUND(F2, d, a, b, c, data[ 2] + 0xfcefa3f8, 9);
128 ROUND(F2, c, d, a, b, data[ 7] + 0x676f02d9, 14);
129 ROUND(F2, b, c, d, a, data[12] + 0x8d2a4c8a, 20); DEBUG(31);
131 ROUND(F3, a, b, c, d, data[ 5] + 0xfffa3942, 4); DEBUG(32);
132 ROUND(F3, d, a, b, c, data[ 8] + 0x8771f681, 11); DEBUG(33);
133 ROUND(F3, c, d, a, b, data[11] + 0x6d9d6122, 16);
134 ROUND(F3, b, c, d, a, data[14] + 0xfde5380c, 23);
135 ROUND(F3, a, b, c, d, data[ 1] + 0xa4beea44, 4);
136 ROUND(F3, d, a, b, c, data[ 4] + 0x4bdecfa9, 11);
137 ROUND(F3, c, d, a, b, data[ 7] + 0xf6bb4b60, 16);
138 ROUND(F3, b, c, d, a, data[10] + 0xbebfbc70, 23);
139 ROUND(F3, a, b, c, d, data[13] + 0x289b7ec6, 4);
140 ROUND(F3, d, a, b, c, data[ 0] + 0xeaa127fa, 11);
141 ROUND(F3, c, d, a, b, data[ 3] + 0xd4ef3085, 16);
142 ROUND(F3, b, c, d, a, data[ 6] + 0x04881d05, 23);
143 ROUND(F3, a, b, c, d, data[ 9] + 0xd9d4d039, 4);
144 ROUND(F3, d, a, b, c, data[12] + 0xe6db99e5, 11);
145 ROUND(F3, c, d, a, b, data[15] + 0x1fa27cf8, 16);
146 ROUND(F3, b, c, d, a, data[ 2] + 0xc4ac5665, 23); DEBUG(47);
148 ROUND(F4, a, b, c, d, data[ 0] + 0xf4292244, 6); DEBUG(48);
149 ROUND(F4, d, a, b, c, data[ 7] + 0x432aff97, 10); DEBUG(49);
150 ROUND(F4, c, d, a, b, data[14] + 0xab9423a7, 15);
151 ROUND(F4, b, c, d, a, data[ 5] + 0xfc93a039, 21);
152 ROUND(F4, a, b, c, d, data[12] + 0x655b59c3, 6);
153 ROUND(F4, d, a, b, c, data[ 3] + 0x8f0ccc92, 10);
154 ROUND(F4, c, d, a, b, data[10] + 0xffeff47d, 15);
155 ROUND(F4, b, c, d, a, data[ 1] + 0x85845dd1, 21);
156 ROUND(F4, a, b, c, d, data[ 8] + 0x6fa87e4f, 6);
157 ROUND(F4, d, a, b, c, data[15] + 0xfe2ce6e0, 10);
158 ROUND(F4, c, d, a, b, data[ 6] + 0xa3014314, 15);
159 ROUND(F4, b, c, d, a, data[13] + 0x4e0811a1, 21);
160 ROUND(F4, a, b, c, d, data[ 4] + 0xf7537e82, 6);
161 ROUND(F4, d, a, b, c, data[11] + 0xbd3af235, 10);
162 ROUND(F4, c, d, a, b, data[ 2] + 0x2ad7d2bb, 15);
163 ROUND(F4, b, c, d, a, data[ 9] + 0xeb86d391, 21); DEBUG(63);
170 fprintf(stderr, "99: %8x %8x %8x %8x\n",
171 digest[0], digest[1], digest[2], digest[3]);