From d245b30a36301ec7344aa193f29d4244e5511452 Mon Sep 17 00:00:00 2001 From: Paul Duncan Date: Tue, 16 Jul 2019 18:09:06 -0400 Subject: working --- sha256.c | 198 +++++++++++++++++++++++++++------------------------------------ 1 file changed, 86 insertions(+), 112 deletions(-) (limited to 'sha256.c') diff --git a/sha256.c b/sha256.c index 268001d..8249a0c 100644 --- a/sha256.c +++ b/sha256.c @@ -5,14 +5,8 @@ // (first 32 bits of the fractional parts of the square roots of the // first 8 primes 2..19): static const uint32_t H[8] = { - 0x6a09e667, - 0xbb67ae85, - 0x3c6ef372, - 0xa54ff53a, - 0x510e527f, - 0x9b05688c, - 0x1f83d9ab, - 0x5be0cd19, + 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, + 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19, }; // round constants @@ -47,39 +41,50 @@ void sha256_init(sha256_t * const ctx) { memcpy(ctx->h, H, sizeof(H)); } +// decode buffer data as 32-bit words (used for the first 16 words) +#define WI(ctx, i) ( \ + (((uint32_t) (ctx)->buf[4 * (i) + 0]) << 24) | \ + (((uint32_t) (ctx)->buf[4 * (i) + 1]) << 16) | \ + (((uint32_t) (ctx)->buf[4 * (i) + 2]) << 8) | \ + ((uint32_t) (ctx)->buf[4 * (i) + 3]) \ +) + static void -sha256_round(sha256_t * const ctx) { - for (size_t i = 0; i < 16; i++) { - ctx->w[i] = ( - (((uint32_t) ctx->buf[4 * i + 0]) << 24) | - (((uint32_t) ctx->buf[4 * i + 1]) << 16) | - (((uint32_t) ctx->buf[4 * i + 2]) << 8) | - ((uint32_t) ctx->buf[4 * i + 3]) - ); - } +sha256_block(sha256_t * const ctx) { + // init first 16 words from buffer + uint32_t w[64] = { + WI(ctx, 0), WI(ctx, 1), WI(ctx, 2), WI(ctx, 3), + WI(ctx, 4), WI(ctx, 5), WI(ctx, 6), WI(ctx, 7), + WI(ctx, 8), WI(ctx, 9), WI(ctx, 10), WI(ctx, 11), + WI(ctx, 12), WI(ctx, 13), WI(ctx, 14), WI(ctx, 15), + 0, + }; - // Extend the first 16 words into the remaining 48 words w[16..63] of the message schedule array: + // Extend the first 16 words into the remaining 48 words w[16..63] of + // the message schedule array + // // for i from 16 to 63 // s0 := (w[i-15] rr 7) xor (w[i-15] rr 18) xor (w[i-15] rs 3) // s1 := (w[i- 2] rr 17) xor (w[i- 2] rr 19) xor (w[i- 2] rs 10) // w[i] := w[i-16] + s0 + w[i-7] + s1 for (size_t i = 16; i < 64; i++) { - const uint32_t w2 = ctx->w[i - 2], - w7 = ctx->w[i - 7], - w15 = ctx->w[i - 15], - w16 = ctx->w[i - 16], + const uint32_t w2 = w[i - 2], + w7 = w[i - 7], + w15 = w[i - 15], + w16 = w[i - 16], s0 = rr(w15, 7) ^ rr(w15, 18) ^ (w15 >> 3), s1 = rr(w2, 17) ^ rr(w2, 19) ^ (w2 >> 10); - ctx->w[i] = w16 + s0 + w7 + s1; + w[i] = w16 + s0 + w7 + s1; } - // Initialize working variables to current hash value: - uint32_t hs[8]; - for (size_t i = 0; i < 8; i++) { - hs[i] = ctx->h[i]; - } + // Initialize working variables to current hash value + uint32_t hs[8] = { + ctx->h[0], ctx->h[1], ctx->h[2], ctx->h[3], + ctx->h[4], ctx->h[5], ctx->h[6], ctx->h[7], + }; - // Compression function main loop: + // Compression function main loop + // // for i from 0 to 63 // S1 := (e rightrotate 6) xor (e rightrotate 11) xor (e rightrotate 25) // ch := (e and f) xor ((not e) and g) @@ -98,8 +103,8 @@ sha256_round(sha256_t * const ctx) { // a := temp1 + temp2 for (size_t i = 0; i < 64; i++) { const uint32_t s1 = rr(hs[4], 6) ^ rr(hs[4], 11) ^ rr(hs[4], 25), - ch = (hs[4] & hs[5]) ^ (~(hs[4]) & hs[6]), - t0 = hs[7] + s1 + ch + K[i] + ctx->w[i], + ch = (hs[4] & hs[5]) ^ ((~(hs[4])) & hs[6]), + t0 = hs[7] + s1 + ch + K[i] + w[i], s0 = rr(hs[0], 2) ^ rr(hs[0], 13) ^ rr(hs[0], 22), mj = (hs[0] & hs[1]) ^ (hs[0] & hs[2]) ^ (hs[1] & hs[2]), t1 = s0 + mj; @@ -115,52 +120,38 @@ sha256_round(sha256_t * const ctx) { } // Add the compressed chunk to the current hash value - for (size_t i = 0; i < 8; i++) { - ctx->h[i] += hs[i]; - } + ctx->h[0] += hs[0]; + ctx->h[1] += hs[1]; + ctx->h[2] += hs[2]; + ctx->h[3] += hs[3]; + ctx->h[4] += hs[4]; + ctx->h[5] += hs[5]; + ctx->h[6] += hs[6]; + ctx->h[7] += hs[7]; } +#undef WI + void sha256_push( sha256_t * const ctx, - const uint8_t *src, - size_t src_len + const uint8_t * const src, + const size_t src_len ) { - ctx->num_bytes += src_len; - - if ((ctx->buf_len + src_len) >= 64) { - const size_t len = 64 - ctx->buf_len; - memcpy(ctx->buf + ctx->buf_len, src, len); - - sha256_round(ctx); - ctx->buf_len = 0; - - src += len; - src_len -= len; - } else { - memcpy(ctx->buf + ctx->buf_len, src, src_len); - ctx->buf_len += src_len; - - src += src_len; - src_len = 0; + for (size_t i = 0; i < src_len; i++) { + ctx->buf[ctx->buf_len] = src[i]; + ctx->buf_len++; + + if (ctx->buf_len == 64) { + sha256_block(ctx); + ctx->buf_len = 0; + } } - while (src_len >= 64) { - memcpy(ctx->buf, src, 64); - - sha256_round(ctx); - ctx->buf_len = 0; - - src += 64; - src_len -= 64; - } - - if (src_len > 0) { - memcpy(ctx->buf, src, src_len); - ctx->buf_len = src_len; - } + ctx->num_bytes += src_len; } -static void sha256_push_u64( +static void +sha256_push_u64( sha256_t * const ctx, const uint64_t val ) { @@ -178,7 +169,8 @@ static void sha256_push_u64( sha256_push(ctx, buf, sizeof(buf)); } -static const uint8_t FOOTER[65] = { +// end of stream padding +static const uint8_t PADDING[65] = { 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -186,60 +178,42 @@ static const uint8_t FOOTER[65] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; +#define WB(ctx, i) \ + ((ctx)->h[i] >> 24) & 0xff, \ + ((ctx)->h[i] >> 16) & 0xff, \ + ((ctx)->h[i] >> 8) & 0xff, \ + ((ctx)->h[i]) & 0xff + void sha256_fini( sha256_t * const ctx, uint8_t * const out ) { const uint64_t num_bytes = ctx->num_bytes; + const size_t pad_len = (65 - ((num_bytes + 1 + 8) % 64)); - { - // push padding - const size_t pad_len = (64 - ((num_bytes + 1 + 8) % 64)) % 64; - sha256_push(ctx, FOOTER, 1 + pad_len); - } + // fprintf(stderr, "ctx->num_bytes (before pad) = %lu\n", ctx->num_bytes); + + // push padding + sha256_push(ctx, PADDING, pad_len); + + // fprintf(stderr, "ctx->num_bytes (before len) = %lu\n", ctx->num_bytes); - // push length - sha256_push_u64(ctx, num_bytes); - - // extract result - const uint8_t src[32] = { - (ctx->h[0] >> 24) & 0xff, - (ctx->h[0] >> 16) & 0xff, - (ctx->h[0] >> 8) & 0xff, - (ctx->h[0]) & 0xff, - (ctx->h[1] >> 24) & 0xff, - (ctx->h[1] >> 16) & 0xff, - (ctx->h[1] >> 8) & 0xff, - (ctx->h[1]) & 0xff, - (ctx->h[2] >> 24) & 0xff, - (ctx->h[2] >> 16) & 0xff, - (ctx->h[2] >> 8) & 0xff, - (ctx->h[2]) & 0xff, - (ctx->h[3] >> 24) & 0xff, - (ctx->h[3] >> 16) & 0xff, - (ctx->h[3] >> 8) & 0xff, - (ctx->h[3]) & 0xff, - (ctx->h[4] >> 24) & 0xff, - (ctx->h[4] >> 16) & 0xff, - (ctx->h[4] >> 8) & 0xff, - (ctx->h[4]) & 0xff, - (ctx->h[5] >> 24) & 0xff, - (ctx->h[5] >> 16) & 0xff, - (ctx->h[5] >> 8) & 0xff, - (ctx->h[5]) & 0xff, - (ctx->h[6] >> 24) & 0xff, - (ctx->h[6] >> 16) & 0xff, - (ctx->h[6] >> 8) & 0xff, - (ctx->h[6]) & 0xff, - (ctx->h[7] >> 24) & 0xff, - (ctx->h[7] >> 16) & 0xff, - (ctx->h[7] >> 8) & 0xff, - (ctx->h[7]) & 0xff, + // push length (in bits) + sha256_push_u64(ctx, num_bytes * 8); + + // fprintf(stderr, "ctx->num_bytes (after len) = %lu\n", ctx->num_bytes); + + // extract hash + const uint8_t hash[32] = { + WB(ctx, 0), WB(ctx, 1), WB(ctx, 2), WB(ctx, 3), + WB(ctx, 4), WB(ctx, 5), WB(ctx, 6), WB(ctx, 7), }; - memcpy(out, src, sizeof(src)); + memcpy(out, hash, sizeof(hash)); } +#undef WB + void sha256( const uint8_t * const src, const size_t src_len, -- cgit v1.2.3