juegos

Juegos de terminal de Pancho: Catan (TUI, GUI, web, servidor, PicoCalc), ajedrez, calculadora y minijuegos
git clone https://git.lu3dhn.xyz/juegos.git
Log | Files | Refs

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 }