- void SHA256Init(SHA256Context *ctx, const unsigned int* key)
- {
- if (key)
- {
- for (int i = 0; i < 8; i++)
- ctx->h[i] = key[i];
- }
- else
- {
- for (int i = 0; i < 8; i++)
- ctx->h[i] = sha256_h0[i];
- }
- ctx->len = 0;
- ctx->tot_len = 0;
- }
-
- void SHA256Transform(SHA256Context *ctx, unsigned char *message, unsigned int block_nb)
- {
- uint32_t w[64];
- uint32_t wv[8];
- unsigned char *sub_block;
- for (unsigned int i = 1; i <= block_nb; i++)
- {
- int j;
- sub_block = message + ((i - 1) << 6);
-
- for (j = 0; j < 16; j++)
- PACK32(&sub_block[j << 2], &w[j]);
- for (j = 16; j < 64; j++)
- SHA256_SCR(j);
- for (j = 0; j < 8; j++)
- wv[j] = ctx->h[j];
- for (j = 0; j < 64; j++)
- {
- uint32_t t1 = wv[7] + SHA256_F2(wv[4]) + CH(wv[4], wv[5], wv[6]) + sha256_k[j] + w[j];
- uint32_t t2 = SHA256_F1(wv[0]) + MAJ(wv[0], wv[1], wv[2]);
- wv[7] = wv[6];
- wv[6] = wv[5];
- wv[5] = wv[4];
- wv[4] = wv[3] + t1;
- wv[3] = wv[2];
- wv[2] = wv[1];
- wv[1] = wv[0];
- wv[0] = t1 + t2;
- }
- for (j = 0; j < 8; j++)
- ctx->h[j] += wv[j];
- }
- }
-
- void SHA256Update(SHA256Context *ctx, unsigned char *message, unsigned int len)
- {
- unsigned int rem_len = SHA256_BLOCK_SIZE - ctx->len;
- memcpy(&ctx->block[ctx->len], message, rem_len);
- if (ctx->len + len < SHA256_BLOCK_SIZE)
- {
- ctx->len += len;
- return;
- }
- unsigned int new_len = len - rem_len;
- unsigned int block_nb = new_len / SHA256_BLOCK_SIZE;
- unsigned char *shifted_message = message + rem_len;
- SHA256Transform(ctx, ctx->block, 1);
- SHA256Transform(ctx, shifted_message, block_nb);
- rem_len = new_len % SHA256_BLOCK_SIZE;
- memcpy(ctx->block, &shifted_message[block_nb << 6],rem_len);
- ctx->len = rem_len;
- ctx->tot_len += (block_nb + 1) << 6;
- }
-
- void SHA256Final(SHA256Context *ctx, unsigned char *digest)
- {
- unsigned int block_nb = (1 + ((SHA256_BLOCK_SIZE - 9) < (ctx->len % SHA256_BLOCK_SIZE)));
- unsigned int len_b = (ctx->tot_len + ctx->len) << 3;
- unsigned int pm_len = block_nb << 6;
- memset(ctx->block + ctx->len, 0, pm_len - ctx->len);
- ctx->block[ctx->len] = 0x80;
- UNPACK32(len_b, ctx->block + pm_len - 4);
- SHA256Transform(ctx, ctx->block, block_nb);
- for (int i = 0 ; i < 8; i++)
- UNPACK32(ctx->h[i], &digest[i << 2]);
- }
-
- void SHA256(const char *src, char *dest, int len, const char* hxc, const unsigned int* key = NULL)
- {
- // Generate the hash
- unsigned char bytehash[SHA256_DIGEST_SIZE];
- SHA256Context ctx;
- SHA256Init(&ctx, key);
- SHA256Update(&ctx, (unsigned char *)src, (unsigned int)len);
- SHA256Final(&ctx, bytehash);
- // Convert it to hex
- for (int i = 0, j = 0; i < SHA256_DIGEST_SIZE; i++)
- {
- dest[j++] = hxc[bytehash[i] / 16];
- dest[j++] = hxc[bytehash[i] % 16];
- dest[j] = '\0';
- }
- }
-
- unsigned int* key;
- char* chars;
-