fetch_ml/native/dataset_hash/crypto/sha256_hasher.cpp
Jeremie Fraeys 37aad7ae87
feat: add manifest signing and native hashing support
- Integrate RunManifest.Validate with existing Validator
- Add manifest Sign() and Verify() methods
- Add native C++ hashing libraries (dataset_hash, queue_index)
- Add native bridge for Go/C++ integration
- Add deduplication support in queue
2026-02-19 15:34:39 -05:00

122 lines
3.5 KiB
C++

#include "sha256_hasher.h"
#include <string.h>
// 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;
}