1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | static void one_shot_sha1(char *input, int len, char *digest) { #define W(t) w[(t) & 0x0F] #define CH(x, y, z) (((x) & (y)) | (~(x) & (z))) #define PARITY(x, y, z) ((x) ^ (y) ^ (z)) #define MAJ(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) #define ROL32(a, n) (((a) << (n)) | ((a) >> (32 - (n)))) #define MIN(a, b) ((a) < (b) ? (a) : (b)) uint32_t k[4] = { 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6 }, h[5] = { 0x67452301, 0xEFCDAB89, 0x98BADCFE,0x10325476, 0xC3D2E1F0}, w[16], sz, temp, t, a, b, c, d, e; int done = 0; uint64_t bits = len * 8; unsigned char pad = 0x80; while (!done) { if (len > 0) { t = MIN(len, 64); memcpy(w, input, t); input += t; len -= t; sz = t; } else sz = 0; if (sz < 56) { ((unsigned char *)w)[sz] = pad; for (t = sz + 1; t < 56; t++) ((unsigned char *)w)[t] = 0; w[14] = htobe32((uint32_t)(bits >> 32)); w[15] = htobe32((uint32_t)bits); done = 1; } else if (sz < 64) { ((unsigned char *)w)[sz] = pad; pad = 0; for (t = sz + 1; t < 64; t++) ((unsigned char *)w)[t] = 0; } for (t = 0; t < 16; t++) w[t] = be32toh(w[t]); a = h[0]; b = h[1]; c = h[2]; d = h[3]; e = h[4]; for (t = 0; t < 80; t++) { if(t >= 16) W(t) = ROL32(W(t + 13) ^ W(t + 8) ^ W(t + 2) ^ W(t), 1); if(t < 20) temp = ROL32(a, 5) + CH(b, c, d) + e + W(t) + k[0]; else if(t < 40) temp = ROL32(a, 5) + PARITY(b, c, d) + e + W(t) + k[1]; else if(t < 60) temp = ROL32(a, 5) + MAJ(b, c, d) + e + W(t) + k[2]; else temp = ROL32(a, 5) + PARITY(b, c, d) + e + W(t) + k[3]; e = d; d = c; c = ROL32(b, 30); b = a; a = temp; } h[0] += a; h[1] += b; h[2] += c; h[3] += d; h[4] += e; } for (t = 0; t < 5; t++) ((uint32_t *)digest)[t] = htobe32(h[t]); } |
参考
https://www.oryx-embedded.com/doc/sha1_8c_source.html