MCPcopy Create free account
hub / github.com/ElementsProject/elements / simplicity_sha256_bitstring

Function simplicity_sha256_bitstring

src/simplicity/sha256.c:157–205  ·  view source on GitHub ↗

Compute the SHA-256 hash, 'h', of the bitstring represented by 's'. * * Precondition: uint32_t h[8]; * '*s' is a valid bitstring; * 's->len < 2^64; */

Source from the content-addressed store, hash-verified

155 * 's->len < 2^64;
156 */
157void simplicity_sha256_bitstring(uint32_t* h, const bitstring* s) {
158 /* This static assert should never fail if uint32_t exists.
159 * But for more certainty, we note that the correctness of this implementation depends on CHAR_BIT being no more than 32.
160 */
161 static_assert(CHAR_BIT <= 32, "CHAR_BIT has to be less than 32 for uint32_t to even exist.");
162
163 uint32_t block[16] = { 0 };
164 size_t count = 0;
165 sha256_iv(h);
166 if (s->len) {
167 block[0] = s->arr[s->offset / CHAR_BIT];
168 if (s->len < CHAR_BIT - s->offset % CHAR_BIT) {
169 /* s->len is so short that we don't even use a whole char.
170 * Zero out the low bits.
171 */
172 block[0] = block[0] >> (CHAR_BIT - s->offset % CHAR_BIT - s->len)
173 << (CHAR_BIT - s->offset % CHAR_BIT - s->len);
174 count = s->len;
175 } else {
176 count = CHAR_BIT - s->offset % CHAR_BIT;
177 }
178 block[0] = 1U * block[0] << (32 - CHAR_BIT + s->offset % CHAR_BIT);
179
180 while (count < s->len) {
181 unsigned char ch = s->arr[(s->offset + count)/CHAR_BIT];
182 size_t delta = CHAR_BIT;
183 if (s->len - count < CHAR_BIT) {
184 delta = s->len - count;
185 /* Zero out any extra low bits that 'ch' may have. */
186 ch = (unsigned char)(ch >> (CHAR_BIT - delta) << (CHAR_BIT - delta));
187 }
188
189 if (count / 32 != (count + CHAR_BIT) / 32) {
190 /* The next character from s->arr straddles (or almost straddles) the boundary of two elements of the block array. */
191 block[count / 32 % 16] |= (uint32_t)((uint_fast32_t)ch >> (count + CHAR_BIT) % 32);
192 if (count / 512 != (count + delta) / 512) {
193 simplicity_sha256_compression(h, block);
194 memset(block, 0, sizeof(uint32_t[16]));
195 }
196 }
197 if ((count + CHAR_BIT) % 32) {
198 block[(count + CHAR_BIT) / 32 % 16] |= (uint32_t)(1U * (uint_fast32_t)ch << (32 - (count + CHAR_BIT) % 32));
199 }
200 count += delta;
201 }
202 }
203 simplicity_assert(count == s->len);
204 sha256_end(h, block, s->len);
205}
206
207#ifndef NO_SHA_NI_FLAG
208#include "sha256_x86.inc"

Callers 2

computeIdentityHashRootsFunction · 0.85

Calls 2

sha256_ivFunction · 0.85
sha256_endFunction · 0.85

Tested by

no test coverage detected