diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2010-10-16 20:46:35 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2010-10-16 20:46:35 +0200 |
commit | bcccad35318004922cc04487e1df4eade4545966 (patch) | |
tree | d65ad2822b4baf2b4c8e0c3ac02cf74879b03573 | |
parent | c0683acce88efc1fe15d9a4332428b5a9fdc6c2e (diff) | |
download | busybox-w32-bcccad35318004922cc04487e1df4eade4545966.tar.gz busybox-w32-bcccad35318004922cc04487e1df4eade4545966.tar.bz2 busybox-w32-bcccad35318004922cc04487e1df4eade4545966.zip |
md5: code shrink; and use 64-byte temp buf, not 128-byte.
function old new delta
md5_hash 111 108 -3
md5_end 129 125 -4
md5_hash_block 459 454 -5
filter_rename_config 250 244 -6
md5_crypt 587 578 -9
popmaildir_main 828 816 -12
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/6 up/down: 0/-39) Total: -39 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | include/libbb.h | 2 | ||||
-rw-r--r-- | include/platform.h | 4 | ||||
-rw-r--r-- | libbb/md5.c | 51 |
3 files changed, 30 insertions, 27 deletions
diff --git a/include/libbb.h b/include/libbb.h index 1031cad8b..f406fc6f1 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -1540,7 +1540,7 @@ typedef struct md5_ctx_t { | |||
1540 | uint32_t C; | 1540 | uint32_t C; |
1541 | uint32_t D; | 1541 | uint32_t D; |
1542 | uint64_t total; | 1542 | uint64_t total; |
1543 | char buffer[128]; | 1543 | char buffer[64]; |
1544 | } md5_ctx_t; | 1544 | } md5_ctx_t; |
1545 | #else | 1545 | #else |
1546 | /* libbb/md5prime.c uses a bit different one: */ | 1546 | /* libbb/md5prime.c uses a bit different one: */ |
diff --git a/include/platform.h b/include/platform.h index 85efa53cd..c255a17ce 100644 --- a/include/platform.h +++ b/include/platform.h | |||
@@ -197,6 +197,8 @@ | |||
197 | # define SWAP_LE16(x) bswap_16(x) | 197 | # define SWAP_LE16(x) bswap_16(x) |
198 | # define SWAP_LE32(x) bswap_32(x) | 198 | # define SWAP_LE32(x) bswap_32(x) |
199 | # define SWAP_LE64(x) bswap_64(x) | 199 | # define SWAP_LE64(x) bswap_64(x) |
200 | # define IF_BIG_ENDIAN(...) __VA_ARGS__ | ||
201 | # define IF_LITTLE_ENDIAN(...) | ||
200 | #else | 202 | #else |
201 | # define SWAP_BE16(x) bswap_16(x) | 203 | # define SWAP_BE16(x) bswap_16(x) |
202 | # define SWAP_BE32(x) bswap_32(x) | 204 | # define SWAP_BE32(x) bswap_32(x) |
@@ -204,6 +206,8 @@ | |||
204 | # define SWAP_LE16(x) (x) | 206 | # define SWAP_LE16(x) (x) |
205 | # define SWAP_LE32(x) (x) | 207 | # define SWAP_LE32(x) (x) |
206 | # define SWAP_LE64(x) (x) | 208 | # define SWAP_LE64(x) (x) |
209 | # define IF_BIG_ENDIAN(...) | ||
210 | # define IF_LITTLE_ENDIAN(...) __VA_ARGS__ | ||
207 | #endif | 211 | #endif |
208 | 212 | ||
209 | /* ---- Unaligned access ------------------------------------ */ | 213 | /* ---- Unaligned access ------------------------------------ */ |
diff --git a/libbb/md5.c b/libbb/md5.c index 47f5fc6f8..3c24bc60b 100644 --- a/libbb/md5.c +++ b/libbb/md5.c | |||
@@ -49,11 +49,8 @@ void FAST_FUNC md5_begin(md5_ctx_t *ctx) | |||
49 | #define rotl32(w, s) (((w) << (s)) | ((w) >> (32 - (s)))) | 49 | #define rotl32(w, s) (((w) << (s)) | ((w) >> (32 - (s)))) |
50 | 50 | ||
51 | /* Hash a single block, 64 bytes long and 4-byte aligned. */ | 51 | /* Hash a single block, 64 bytes long and 4-byte aligned. */ |
52 | static void md5_hash_block(md5_ctx_t *ctx, const void *buffer) | 52 | static void md5_hash_block(md5_ctx_t *ctx) |
53 | { | 53 | { |
54 | uint32_t correct_words[16]; | ||
55 | const uint32_t *words = buffer; | ||
56 | |||
57 | #if MD5_SIZE_VS_SPEED > 0 | 54 | #if MD5_SIZE_VS_SPEED > 0 |
58 | /* Before we start, one word to the strange constants. | 55 | /* Before we start, one word to the strange constants. |
59 | They are defined in RFC 1321 as | 56 | They are defined in RFC 1321 as |
@@ -98,12 +95,13 @@ static void md5_hash_block(md5_ctx_t *ctx, const void *buffer) | |||
98 | }; | 95 | }; |
99 | # endif | 96 | # endif |
100 | #endif | 97 | #endif |
98 | const uint32_t *words = (const void*) ctx->buffer; | ||
99 | |||
101 | uint32_t A = ctx->A; | 100 | uint32_t A = ctx->A; |
102 | uint32_t B = ctx->B; | 101 | uint32_t B = ctx->B; |
103 | uint32_t C = ctx->C; | 102 | uint32_t C = ctx->C; |
104 | uint32_t D = ctx->D; | 103 | uint32_t D = ctx->D; |
105 | 104 | ||
106 | uint32_t *cwp = correct_words; | ||
107 | uint32_t A_save = A; | 105 | uint32_t A_save = A; |
108 | uint32_t B_save = B; | 106 | uint32_t B_save = B; |
109 | uint32_t C_save = C; | 107 | uint32_t C_save = C; |
@@ -116,9 +114,10 @@ static void md5_hash_block(md5_ctx_t *ctx, const void *buffer) | |||
116 | int i; | 114 | int i; |
117 | uint32_t temp; | 115 | uint32_t temp; |
118 | 116 | ||
117 | # if BB_BIG_ENDIAN | ||
119 | for (i = 0; i < 16; i++) | 118 | for (i = 0; i < 16; i++) |
120 | cwp[i] = SWAP_LE32(words[i]); | 119 | words[i] = SWAP_LE32(words[i]); |
121 | words += 16; | 120 | # endif |
122 | 121 | ||
123 | # if MD5_SIZE_VS_SPEED > 2 | 122 | # if MD5_SIZE_VS_SPEED > 2 |
124 | pc = C_array; | 123 | pc = C_array; |
@@ -142,7 +141,7 @@ static void md5_hash_block(md5_ctx_t *ctx, const void *buffer) | |||
142 | case 3: | 141 | case 3: |
143 | temp += FI(B, C, D); | 142 | temp += FI(B, C, D); |
144 | } | 143 | } |
145 | temp += cwp[(int) (*pp++)] + *pc++; | 144 | temp += words[(int) (*pp++)] + *pc++; |
146 | temp = rotl32(temp, ps[i & 3]); | 145 | temp = rotl32(temp, ps[i & 3]); |
147 | temp += B; | 146 | temp += B; |
148 | A = D; | 147 | A = D; |
@@ -156,7 +155,7 @@ static void md5_hash_block(md5_ctx_t *ctx, const void *buffer) | |||
156 | ps = S_array; | 155 | ps = S_array; |
157 | 156 | ||
158 | for (i = 0; i < 16; i++) { | 157 | for (i = 0; i < 16; i++) { |
159 | temp = A + FF(B, C, D) + cwp[(int) (*pp++)] + *pc++; | 158 | temp = A + FF(B, C, D) + words[(int) (*pp++)] + *pc++; |
160 | temp = rotl32(temp, ps[i & 3]); | 159 | temp = rotl32(temp, ps[i & 3]); |
161 | temp += B; | 160 | temp += B; |
162 | A = D; | 161 | A = D; |
@@ -166,7 +165,7 @@ static void md5_hash_block(md5_ctx_t *ctx, const void *buffer) | |||
166 | } | 165 | } |
167 | ps += 4; | 166 | ps += 4; |
168 | for (i = 0; i < 16; i++) { | 167 | for (i = 0; i < 16; i++) { |
169 | temp = A + FG(B, C, D) + cwp[(int) (*pp++)] + *pc++; | 168 | temp = A + FG(B, C, D) + words[(int) (*pp++)] + *pc++; |
170 | temp = rotl32(temp, ps[i & 3]); | 169 | temp = rotl32(temp, ps[i & 3]); |
171 | temp += B; | 170 | temp += B; |
172 | A = D; | 171 | A = D; |
@@ -176,7 +175,7 @@ static void md5_hash_block(md5_ctx_t *ctx, const void *buffer) | |||
176 | } | 175 | } |
177 | ps += 4; | 176 | ps += 4; |
178 | for (i = 0; i < 16; i++) { | 177 | for (i = 0; i < 16; i++) { |
179 | temp = A + FH(B, C, D) + cwp[(int) (*pp++)] + *pc++; | 178 | temp = A + FH(B, C, D) + words[(int) (*pp++)] + *pc++; |
180 | temp = rotl32(temp, ps[i & 3]); | 179 | temp = rotl32(temp, ps[i & 3]); |
181 | temp += B; | 180 | temp += B; |
182 | A = D; | 181 | A = D; |
@@ -186,7 +185,7 @@ static void md5_hash_block(md5_ctx_t *ctx, const void *buffer) | |||
186 | } | 185 | } |
187 | ps += 4; | 186 | ps += 4; |
188 | for (i = 0; i < 16; i++) { | 187 | for (i = 0; i < 16; i++) { |
189 | temp = A + FI(B, C, D) + cwp[(int) (*pp++)] + *pc++; | 188 | temp = A + FI(B, C, D) + words[(int) (*pp++)] + *pc++; |
190 | temp = rotl32(temp, ps[i & 3]); | 189 | temp = rotl32(temp, ps[i & 3]); |
191 | temp += B; | 190 | temp += B; |
192 | A = D; | 191 | A = D; |
@@ -203,12 +202,12 @@ static void md5_hash_block(md5_ctx_t *ctx, const void *buffer) | |||
203 | unit is a 32-bit word and it is determined to work on words in | 202 | unit is a 32-bit word and it is determined to work on words in |
204 | little endian byte order we perhaps have to change the byte order | 203 | little endian byte order we perhaps have to change the byte order |
205 | before the computation. To reduce the work for the next steps | 204 | before the computation. To reduce the work for the next steps |
206 | we store the swapped words in the array CORRECT_WORDS. */ | 205 | we save swapped words in WORDS array. */ |
207 | # undef OP | 206 | # undef OP |
208 | # define OP(a, b, c, d, s, T) \ | 207 | # define OP(a, b, c, d, s, T) \ |
209 | do { \ | 208 | do { \ |
210 | a += FF(b, c, d) + (*cwp++ = SWAP_LE32(*words)) + T; \ | 209 | a += FF(b, c, d) + (*words IF_BIG_ENDIAN(= SWAP_LE32(*words))) + T; \ |
211 | ++words; \ | 210 | words++; \ |
212 | a = rotl32(a, s); \ | 211 | a = rotl32(a, s); \ |
213 | a += b; \ | 212 | a += b; \ |
214 | } while (0) | 213 | } while (0) |
@@ -248,7 +247,7 @@ static void md5_hash_block(md5_ctx_t *ctx, const void *buffer) | |||
248 | # endif | 247 | # endif |
249 | 248 | ||
250 | /* For the second to fourth round we have the possibly swapped words | 249 | /* For the second to fourth round we have the possibly swapped words |
251 | in CORRECT_WORDS. Redefine the macro to take an additional first | 250 | in WORDS. Redefine the macro to take an additional first |
252 | argument specifying the function to use. */ | 251 | argument specifying the function to use. */ |
253 | # undef OP | 252 | # undef OP |
254 | # define OP(f, a, b, c, d, k, s, T) \ | 253 | # define OP(f, a, b, c, d, k, s, T) \ |
@@ -385,7 +384,7 @@ void FAST_FUNC md5_hash(md5_ctx_t *ctx, const void *buffer, size_t len) | |||
385 | if (buflen != 0) | 384 | if (buflen != 0) |
386 | break; | 385 | break; |
387 | /* Buffer is filled up, process it. */ | 386 | /* Buffer is filled up, process it. */ |
388 | md5_hash_block(ctx, ctx->buffer); | 387 | md5_hash_block(ctx); |
389 | /*buflen = 0; - already is */ | 388 | /*buflen = 0; - already is */ |
390 | } | 389 | } |
391 | } | 390 | } |
@@ -398,29 +397,29 @@ void FAST_FUNC md5_hash(md5_ctx_t *ctx, const void *buffer, size_t len) | |||
398 | void FAST_FUNC md5_end(md5_ctx_t *ctx, void *resbuf) | 397 | void FAST_FUNC md5_end(md5_ctx_t *ctx, void *resbuf) |
399 | { | 398 | { |
400 | uint64_t total; | 399 | uint64_t total; |
401 | char *buf = ctx->buffer; | ||
402 | unsigned i; | 400 | unsigned i; |
403 | unsigned buflen = BUFLEN(ctx); | 401 | unsigned buflen = BUFLEN(ctx); |
404 | 402 | ||
405 | /* Pad data to block size. */ | 403 | /* Pad data to block size. */ |
406 | buf[buflen++] = 0x80; | 404 | ctx->buffer[buflen++] = 0x80; |
407 | memset(buf + buflen, 0, 128 - buflen); | 405 | memset(ctx->buffer + buflen, 0, 64 - buflen); |
406 | |||
407 | if (buflen > 56) { | ||
408 | md5_hash_block(ctx); | ||
409 | memset(ctx->buffer, 0, 64); | ||
410 | } | ||
408 | 411 | ||
409 | /* Put the 64-bit file length, expressed in *bits*, | 412 | /* Put the 64-bit file length, expressed in *bits*, |
410 | * at the end of the buffer. | 413 | * at the end of the buffer. |
411 | */ | 414 | */ |
412 | /* clever way to do "if (buflen > 56) buf += 64": */ | ||
413 | buf += ((buflen + 7) & 64); | ||
414 | total = ctx->total << 3; | 415 | total = ctx->total << 3; |
415 | for (i = 0; i < 8; i++) { | 416 | for (i = 0; i < 8; i++) { |
416 | buf[56 + i] = total; | 417 | ctx->buffer[56 + i] = total; |
417 | total >>= 8; | 418 | total >>= 8; |
418 | } | 419 | } |
419 | 420 | ||
420 | /* Process last bytes. */ | 421 | /* Process last bytes. */ |
421 | if (buf != ctx->buffer) | 422 | md5_hash_block(ctx); |
422 | md5_hash_block(ctx, ctx->buffer); | ||
423 | md5_hash_block(ctx, buf); | ||
424 | 423 | ||
425 | /* The MD5 result is in little endian byte order. | 424 | /* The MD5 result is in little endian byte order. |
426 | * We (ab)use the fact that A-D are consecutive in memory. | 425 | * We (ab)use the fact that A-D are consecutive in memory. |