13 0x428a2f98u, 0x71374491u, 0xb5c0fbcfu, 0xe9b5dba5u, 0x3956c25bu, 0x59f111f1u, 0x923f82a4u, 0xab1c5ed5u,
14 0xd807aa98u, 0x12835b01u, 0x243185beu, 0x550c7dc3u, 0x72be5d74u, 0x80deb1feu, 0x9bdc06a7u, 0xc19bf174u,
15 0xe49b69c1u, 0xefbe4786u, 0x0fc19dc6u, 0x240ca1ccu, 0x2de92c6fu, 0x4a7484aau, 0x5cb0a9dcu, 0x76f988dau,
16 0x983e5152u, 0xa831c66du, 0xb00327c8u, 0xbf597fc7u, 0xc6e00bf3u, 0xd5a79147u, 0x06ca6351u, 0x14292967u,
17 0x27b70a85u, 0x2e1b2138u, 0x4d2c6dfcu, 0x53380d13u, 0x650a7354u, 0x766a0abbu, 0x81c2c92eu, 0x92722c85u,
18 0xa2bfe8a1u, 0xa81a664bu, 0xc24b8b70u, 0xc76c51a3u, 0xd192e819u, 0xd6990624u, 0xf40e3585u, 0x106aa070u,
19 0x19a4c116u, 0x1e376c08u, 0x2748774cu, 0x34b0bcb5u, 0x391c0cb3u, 0x4ed8aa4au, 0x5b9cca4fu, 0x682e6ff3u,
20 0x748f82eeu, 0x78a5636fu, 0x84c87814u, 0x8cc70208u, 0x90befffau, 0xa4506cebu, 0xbef9a3f7u, 0xc67178f2u
27 uint32_t a, b, c, d, e, f, g, h;
29 for (
size_t index = 0; index < 16; ++index) {
30 const size_t offset = 4 * index;
31 words[index] = ((uint32_t)block[offset] << 24) |
32 ((uint32_t)block[offset + 1] << 16) |
33 ((uint32_t)block[offset + 2] << 8) |
34 (uint32_t)block[offset + 3];
36 for (
size_t index = 16; index < 64; ++index) {
37 const uint32_t s0 =
ROTATE_RIGHT(words[index - 15], 7) ^
ROTATE_RIGHT(words[index - 15], 18) ^ (words[index - 15] >> 3);
38 const uint32_t s1 =
ROTATE_RIGHT(words[index - 2], 17) ^
ROTATE_RIGHT(words[index - 2], 19) ^ (words[index - 2] >> 10);
39 words[index] = words[index - 16] + s0 + words[index - 7] + s1;
45 for (
size_t index = 0; index < 64; ++index) {
47 const uint32_t choose = (e & f) ^ ((~e) & g);
48 const uint32_t temp1 = h + sum1 + choose +
kRoundConstants[index] + words[index];
50 const uint32_t majority = (a & b) ^ (a & c) ^ (b & c);
51 const uint32_t temp2 = sum0 + majority;
53 h = g; g = f; f = e; e = d + temp1;
54 d = c; c = b; b = a; a = temp1 + temp2;
100 static const char hex[] =
"0123456789abcdef";
101 unsigned char digest[32];
102 const uint64_t message_bits = context ? context->
bit_count : 0;
103 unsigned char padding[128] = {0x80};
104 size_t padding_length;
106 if (!context || !digest_hex)
return;
111 for (
size_t index = 0; index < 8; ++index) {
112 context->
buffer[56 + index] = (
unsigned char)(message_bits >> (56 - 8 * index));
116 for (
size_t index = 0; index < 8; ++index) {
117 digest[4 * index] = (
unsigned char)(context->
state[index] >> 24);
118 digest[4 * index + 1] = (
unsigned char)(context->
state[index] >> 16);
119 digest[4 * index + 2] = (
unsigned char)(context->
state[index] >> 8);
120 digest[4 * index + 3] = (
unsigned char)context->
state[index];
122 for (
size_t index = 0; index <
sizeof(digest); ++index) {
123 digest_hex[2 * index] = hex[digest[index] >> 4];
124 digest_hex[2 * index + 1] = hex[digest[index] & 0x0f];
126 digest_hex[64] =
'\0';
133 unsigned char buffer[8192];
136 PetscFunctionBeginUser;
137 PetscCheck(path != NULL && digest_hex != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
138 "SHA-256 file path and digest output are required.");
139 file = fopen(path,
"rb");
140 PetscCheck(file != NULL, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN,
141 "Unable to open '%s' while computing SHA-256.", path);
144 while (!feof(file)) {
145 const size_t count = fread(buffer, 1,
sizeof(buffer), file);
147 PetscCheck(!ferror(file), PETSC_COMM_SELF, PETSC_ERR_FILE_READ,
148 "Unable to read '%s' while computing SHA-256.", path);
150 PetscCheck(fclose(file) == 0, PETSC_COMM_SELF, PETSC_ERR_FILE_READ,
151 "Unable to close '%s' after computing SHA-256.", path);
153 PetscFunctionReturn(0);
Incremental SHA-256 state.