#include "sha256_hasher.h" #include // Platform detection declarations (from other cpp files) TransformFunc detect_x86_transform(void); TransformFunc detect_armv8_transform(void); void sha256_init(Sha256State* hasher) { hasher->buffer_len = 0; hasher->total_len = 0; memcpy(hasher->state, H0, sizeof(H0)); // Detect best transform implementation TransformFunc f = detect_best_transform(); hasher->transform_fn = f ? f : transform_generic; } void sha256_update(Sha256State* hasher, const uint8_t* data, size_t len) { hasher->total_len += len; // Fill buffer if there's pending data if (hasher->buffer_len > 0) { size_t space = 64 - hasher->buffer_len; size_t to_copy = len < space ? len : space; memcpy(hasher->buffer + hasher->buffer_len, data, to_copy); hasher->buffer_len += to_copy; data += to_copy; len -= to_copy; if (hasher->buffer_len == 64) { hasher->transform_fn(hasher->state, hasher->buffer); hasher->buffer_len = 0; } } // Process full blocks while (len >= 64) { hasher->transform_fn(hasher->state, data); data += 64; len -= 64; } // Store remaining data if (len > 0) { memcpy(hasher->buffer, data, len); hasher->buffer_len = len; } } static void sha256_pad_and_finalize(Sha256State* hasher) { uint64_t bit_len = hasher->total_len * 8; // Padding hasher->buffer[hasher->buffer_len++] = 0x80; if (hasher->buffer_len > 56) { while (hasher->buffer_len < 64) hasher->buffer[hasher->buffer_len++] = 0; hasher->transform_fn(hasher->state, hasher->buffer); hasher->buffer_len = 0; } while (hasher->buffer_len < 56) hasher->buffer[hasher->buffer_len++] = 0; // Append length (big-endian) for (int i = 7; i >= 0; --i) { hasher->buffer[56 + (7 - i)] = (bit_len >> (i * 8)) & 0xff; } hasher->transform_fn(hasher->state, hasher->buffer); } void sha256_finalize(Sha256State* hasher, uint8_t out[32]) { sha256_pad_and_finalize(hasher); // Output (big-endian) for (int i = 0; i < 8; ++i) { out[i * 4] = (hasher->state[i] >> 24) & 0xff; out[i * 4 + 1] = (hasher->state[i] >> 16) & 0xff; out[i * 4 + 2] = (hasher->state[i] >> 8) & 0xff; out[i * 4 + 3] = hasher->state[i] & 0xff; } } static void bytes_to_hex(const uint8_t data[32], char* out) { static const char hex[] = "0123456789abcdef"; for (int i = 0; i < 32; ++i) { out[i * 2] = hex[(data[i] >> 4) & 0xf]; out[i * 2 + 1] = hex[data[i] & 0xf]; } out[64] = '\0'; } void sha256_hash_to_hex(const uint8_t* data, size_t len, char* out_hex) { Sha256State hasher; sha256_init(&hasher); sha256_update(&hasher, data, len); uint8_t result[32]; sha256_finalize(&hasher, result); bytes_to_hex(result, out_hex); } TransformFunc detect_best_transform(void) { // Try platform-specific first TransformFunc f = detect_armv8_transform(); if (f) return f; f = detect_x86_transform(); if (f) return f; return transform_generic; } const char* sha256_impl_name(void) { TransformFunc f = detect_best_transform(); TransformFunc arm = detect_armv8_transform(); TransformFunc x86 = detect_x86_transform(); if (f == arm) return "ARMv8"; if (f == x86) return "SHA-NI"; return "generic"; } int sha256_has_hardware_accel(void) { return detect_best_transform() != transform_generic; }