- 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
122 lines
3.5 KiB
C++
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;
|
|
}
|