/* sha256.c — 紧凑 SHA-256(FIPS 180-4),公开领域参考写法,-Wall -Wextra 0 warning。 * 流式 context;meow_verify / meow_sign 共用。 */ #include "sha256.h" #include static const uint32_t K[64] = { 0x428a2f98u,0x71374491u,0xb5c0fbcfu,0xe9b5dba5u,0x3956c25bu,0x59f111f1u,0x923f82a4u,0xab1c5ed5u, 0xd807aa98u,0x12835b01u,0x243185beu,0x550c7dc3u,0x72be5d74u,0x80deb1feu,0x9bdc06a7u,0xc19bf174u, 0xe49b69c1u,0xefbe4786u,0x0fc19dc6u,0x240ca1ccu,0x2de92c6fu,0x4a7484aau,0x5cb0a9dcu,0x76f988dau, 0x983e5152u,0xa831c66du,0xb00327c8u,0xbf597fc7u,0xc6e00bf3u,0xd5a79147u,0x06ca6351u,0x14292967u, 0x27b70a85u,0x2e1b2138u,0x4d2c6dfcu,0x53380d13u,0x650a7354u,0x766a0abbu,0x81c2c92eu,0x92722c85u, 0xa2bfe8a1u,0xa81a664bu,0xc24b8b70u,0xc76c51a3u,0xd192e819u,0xd6990624u,0xf40e3585u,0x106aa070u, 0x19a4c116u,0x1e376c08u,0x2748774cu,0x34b0bcb5u,0x391c0cb3u,0x4ed8aa4au,0x5b9cca4fu,0x682e6ff3u, 0x748f82eeu,0x78a5636fu,0x84c87814u,0x8cc70208u,0x90befffau,0xa4506cebu,0xbef9a3f7u,0xc67178f2u }; #define ROR(x,n) (((x) >> (n)) | ((x) << (32 - (n)))) #define CH(x,y,z) (((x) & (y)) ^ (~(x) & (z))) #define MAJ(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) #define BSIG0(x) (ROR(x,2) ^ ROR(x,13) ^ ROR(x,22)) #define BSIG1(x) (ROR(x,6) ^ ROR(x,11) ^ ROR(x,25)) #define SSIG0(x) (ROR(x,7) ^ ROR(x,18) ^ ((x) >> 3)) #define SSIG1(x) (ROR(x,17) ^ ROR(x,19) ^ ((x) >> 10)) void meow_sha256_init(meow_sha256_ctx *c) { c->state[0] = 0x6a09e667u; c->state[1] = 0xbb67ae85u; c->state[2] = 0x3c6ef372u; c->state[3] = 0xa54ff53au; c->state[4] = 0x510e527fu; c->state[5] = 0x9b05688cu; c->state[6] = 0x1f83d9abu; c->state[7] = 0x5be0cd19u; c->count = 0; c->buflen = 0; } static void sha256_block(meow_sha256_ctx *c, const uint8_t *p) { uint32_t w[64]; int i; for (i = 0; i < 16; i++) { w[i] = ((uint32_t)p[i*4] << 24) | ((uint32_t)p[i*4+1] << 16) | ((uint32_t)p[i*4+2] << 8) | (uint32_t)p[i*4+3]; } for (i = 16; i < 64; i++) w[i] = SSIG1(w[i-2]) + w[i-7] + SSIG0(w[i-15]) + w[i-16]; uint32_t a = c->state[0], b = c->state[1], cc = c->state[2], d = c->state[3]; uint32_t e = c->state[4], f = c->state[5], g = c->state[6], h = c->state[7]; for (i = 0; i < 64; i++) { uint32_t t1 = h + BSIG1(e) + CH(e,f,g) + K[i] + w[i]; uint32_t t2 = BSIG0(a) + MAJ(a,b,cc); h = g; g = f; f = e; e = d + t1; d = cc; cc = b; b = a; a = t1 + t2; } c->state[0] += a; c->state[1] += b; c->state[2] += cc; c->state[3] += d; c->state[4] += e; c->state[5] += f; c->state[6] += g; c->state[7] += h; } void meow_sha256_update(meow_sha256_ctx *c, const uint8_t *data, size_t len) { c->count += (uint64_t)len; /* 先补满残余块 */ if (c->buflen) { size_t need = 64 - c->buflen; size_t take = len < need ? len : need; memcpy(c->buf + c->buflen, data, take); c->buflen += take; data += take; len -= take; if (c->buflen == 64) { sha256_block(c, c->buf); c->buflen = 0; } } while (len >= 64) { sha256_block(c, data); data += 64; len -= 64; } if (len) { memcpy(c->buf, data, len); c->buflen = len; } } void meow_sha256_final(meow_sha256_ctx *c, uint8_t out[32]) { uint64_t bitlen = c->count * 8; uint8_t *b = c->buf; size_t bl = c->buflen; int i; b[bl++] = 0x80; /* 填充:1 位 1 */ if (bl > 56) { /* 一块放不下长度 → 补齐到 64 后压一块 */ while (bl < 64) b[bl++] = 0; sha256_block(c, b); bl = 0; } while (bl < 56) b[bl++] = 0; /* 补到 56 */ for (i = 0; i < 8; i++) /* 大端 64 位 bit 长度 */ b[bl++] = (uint8_t)(bitlen >> (56 - i * 8)); sha256_block(c, b); for (i = 0; i < 8; i++) { out[i*4] = (uint8_t)(c->state[i] >> 24); out[i*4+1] = (uint8_t)(c->state[i] >> 16); out[i*4+2] = (uint8_t)(c->state[i] >> 8); out[i*4+3] = (uint8_t)(c->state[i]); } }