kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

sha256.c (3375B)


      1 #include "core/sha256.h"
      2 
      3 #include <string.h>
      4 
      5 static const u32 SHA256_K[64] = {
      6     0x428a2f98u, 0x71374491u, 0xb5c0fbcfu, 0xe9b5dba5u, 0x3956c25bu,
      7     0x59f111f1u, 0x923f82a4u, 0xab1c5ed5u, 0xd807aa98u, 0x12835b01u,
      8     0x243185beu, 0x550c7dc3u, 0x72be5d74u, 0x80deb1feu, 0x9bdc06a7u,
      9     0xc19bf174u, 0xe49b69c1u, 0xefbe4786u, 0x0fc19dc6u, 0x240ca1ccu,
     10     0x2de92c6fu, 0x4a7484aau, 0x5cb0a9dcu, 0x76f988dau, 0x983e5152u,
     11     0xa831c66du, 0xb00327c8u, 0xbf597fc7u, 0xc6e00bf3u, 0xd5a79147u,
     12     0x06ca6351u, 0x14292967u, 0x27b70a85u, 0x2e1b2138u, 0x4d2c6dfcu,
     13     0x53380d13u, 0x650a7354u, 0x766a0abbu, 0x81c2c92eu, 0x92722c85u,
     14     0xa2bfe8a1u, 0xa81a664bu, 0xc24b8b70u, 0xc76c51a3u, 0xd192e819u,
     15     0xd6990624u, 0xf40e3585u, 0x106aa070u, 0x19a4c116u, 0x1e376c08u,
     16     0x2748774cu, 0x34b0bcb5u, 0x391c0cb3u, 0x4ed8aa4au, 0x5b9cca4fu,
     17     0x682e6ff3u, 0x748f82eeu, 0x78a5636fu, 0x84c87814u, 0x8cc70208u,
     18     0x90befffau, 0xa4506cebu, 0xbef9a3f7u, 0xc67178f2u};
     19 
     20 static u32 sha256_rotr32(u32 v, u32 n) { return (v >> n) | (v << (32 - n)); }
     21 
     22 void sha256_init(Sha256* s) {
     23   s->h[0] = 0x6a09e667u;
     24   s->h[1] = 0xbb67ae85u;
     25   s->h[2] = 0x3c6ef372u;
     26   s->h[3] = 0xa54ff53au;
     27   s->h[4] = 0x510e527fu;
     28   s->h[5] = 0x9b05688cu;
     29   s->h[6] = 0x1f83d9abu;
     30   s->h[7] = 0x5be0cd19u;
     31   s->buflen = 0;
     32   s->total = 0;
     33 }
     34 
     35 static void sha256_block(Sha256* s, const u8* p) {
     36   u32 w[64];
     37   for (u32 i = 0; i < 16; ++i)
     38     w[i] = ((u32)p[i * 4] << 24) | ((u32)p[i * 4 + 1] << 16) |
     39            ((u32)p[i * 4 + 2] << 8) | (u32)p[i * 4 + 3];
     40   for (u32 i = 16; i < 64; ++i) {
     41     u32 s0 = sha256_rotr32(w[i - 15], 7) ^ sha256_rotr32(w[i - 15], 18) ^
     42              (w[i - 15] >> 3);
     43     u32 s1 = sha256_rotr32(w[i - 2], 17) ^ sha256_rotr32(w[i - 2], 19) ^
     44              (w[i - 2] >> 10);
     45     w[i] = w[i - 16] + s0 + w[i - 7] + s1;
     46   }
     47   u32 a = s->h[0], b = s->h[1], cc = s->h[2], d = s->h[3];
     48   u32 e = s->h[4], f = s->h[5], g = s->h[6], hh = s->h[7];
     49   for (u32 i = 0; i < 64; ++i) {
     50     u32 S1 = sha256_rotr32(e, 6) ^ sha256_rotr32(e, 11) ^ sha256_rotr32(e, 25);
     51     u32 ch = (e & f) ^ ((~e) & g);
     52     u32 t1 = hh + S1 + ch + SHA256_K[i] + w[i];
     53     u32 S0 = sha256_rotr32(a, 2) ^ sha256_rotr32(a, 13) ^ sha256_rotr32(a, 22);
     54     u32 mj = (a & b) ^ (a & cc) ^ (b & cc);
     55     u32 t2 = S0 + mj;
     56     hh = g;
     57     g = f;
     58     f = e;
     59     e = d + t1;
     60     d = cc;
     61     cc = b;
     62     b = a;
     63     a = t1 + t2;
     64   }
     65   s->h[0] += a;
     66   s->h[1] += b;
     67   s->h[2] += cc;
     68   s->h[3] += d;
     69   s->h[4] += e;
     70   s->h[5] += f;
     71   s->h[6] += g;
     72   s->h[7] += hh;
     73 }
     74 
     75 void sha256_update(Sha256* s, const u8* data, u32 n) {
     76   s->total += n;
     77   while (n) {
     78     u32 take = 64u - s->buflen;
     79     if (take > n) take = n;
     80     memcpy(s->buf + s->buflen, data, take);
     81     s->buflen += take;
     82     data += take;
     83     n -= take;
     84     if (s->buflen == 64) {
     85       sha256_block(s, s->buf);
     86       s->buflen = 0;
     87     }
     88   }
     89 }
     90 
     91 void sha256_final(Sha256* s, u8 out[SHA256_DIGEST_LEN]) {
     92   u64 bits = s->total * 8u;
     93   u8 pad1 = 0x80;
     94   sha256_update(s, &pad1, 1);
     95   while (s->buflen != 56) {
     96     u8 z = 0;
     97     sha256_update(s, &z, 1);
     98   }
     99   u8 lenbe[8];
    100   for (u32 i = 0; i < 8; ++i) lenbe[7 - i] = (u8)(bits >> (i * 8));
    101   sha256_update(s, lenbe, 8);
    102   for (u32 i = 0; i < 8; ++i) {
    103     out[i * 4 + 0] = (u8)(s->h[i] >> 24);
    104     out[i * 4 + 1] = (u8)(s->h[i] >> 16);
    105     out[i * 4 + 2] = (u8)(s->h[i] >> 8);
    106     out[i * 4 + 3] = (u8)(s->h[i]);
    107   }
    108 }