sha1.c (2517B)
1 /* sha1.c - SHA-1 en un solo bloque de memoria, y base64. */ 2 #include <string.h> 3 #include "sha1.h" 4 5 #define ROL(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) 6 7 static void block(uint32_t h[5], const uint8_t *p) 8 { 9 uint32_t w[80]; 10 for (int i = 0; i < 16; i++) 11 w[i] = (uint32_t)p[4 * i] << 24 | (uint32_t)p[4 * i + 1] << 16 | (uint32_t)p[4 * i + 2] << 8 | p[4 * i + 3]; 12 for (int i = 16; i < 80; i++) w[i] = ROL(w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16], 1); 13 uint32_t a = h[0], b = h[1], c = h[2], d = h[3], e = h[4]; 14 for (int i = 0; i < 80; i++) { 15 uint32_t f, k; 16 if (i < 20) { f = (b & c) | (~b & d); k = 0x5a827999; } 17 else if (i < 40) { f = b ^ c ^ d; k = 0x6ed9eba1; } 18 else if (i < 60) { f = (b & c) | (b & d) | (c & d); k = 0x8f1bbcdc; } 19 else { f = b ^ c ^ d; k = 0xca62c1d6; } 20 uint32_t t = ROL(a, 5) + f + e + k + w[i]; 21 e = d; d = c; c = ROL(b, 30); b = a; a = t; 22 } 23 h[0] += a; h[1] += b; h[2] += c; h[3] += d; h[4] += e; 24 } 25 26 void sha1(const void *data, size_t len, uint8_t out[20]) 27 { 28 uint32_t h[5] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 }; 29 const uint8_t *p = data; 30 size_t i = 0; 31 for (; i + 64 <= len; i += 64) block(h, p + i); 32 uint8_t tail[128]; 33 size_t rest = len - i; 34 memcpy(tail, p + i, rest); 35 tail[rest++] = 0x80; 36 size_t total = rest <= 56 ? 64 : 128; 37 memset(tail + rest, 0, total - rest); 38 uint64_t bits = (uint64_t)len * 8; 39 for (int k = 0; k < 8; k++) tail[total - 1 - k] = (uint8_t)(bits >> (8 * k)); 40 block(h, tail); 41 if (total == 128) block(h, tail + 64); 42 for (int k = 0; k < 5; k++) { 43 out[4 * k] = (uint8_t)(h[k] >> 24); out[4 * k + 1] = (uint8_t)(h[k] >> 16); 44 out[4 * k + 2] = (uint8_t)(h[k] >> 8); out[4 * k + 3] = (uint8_t)h[k]; 45 } 46 } 47 48 int base64_encode(const void *data, size_t n, char *out, size_t cap) 49 { 50 static const char T[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 51 size_t need = (n + 2) / 3 * 4; 52 if (need + 1 > cap) return -1; 53 const uint8_t *p = data; 54 size_t o = 0; 55 for (size_t i = 0; i < n; i += 3) { 56 uint32_t v = (uint32_t)p[i] << 16; 57 if (i + 1 < n) v |= (uint32_t)p[i + 1] << 8; 58 if (i + 2 < n) v |= p[i + 2]; 59 out[o++] = T[(v >> 18) & 63]; 60 out[o++] = T[(v >> 12) & 63]; 61 out[o++] = i + 1 < n ? T[(v >> 6) & 63] : '='; 62 out[o++] = i + 2 < n ? T[v & 63] : '='; 63 } 64 out[o] = 0; 65 return (int)o; 66 }