| #include <stdint.h>
|
| #include <stddef.h>
|
| #include "cuda_validation_chain.h"
|
|
|
| |
| |
| |
|
|
|
|
| static void fnv256_init(uint8_t* h) {
|
|
|
| static const uint8_t BASIS[32] = {
|
| 0xdd,0x26,0x8d,0xbc,0xaa,0xe0,0x94,0x84,
|
| 0xdb,0x9f,0x6a,0xae,0x0c,0x41,0x4b,0x41,
|
| 0x21,0x72,0x24,0xd1,0x0d,0x3b,0x26,0x1d,
|
| 0xc4,0xef,0x15,0x81,0x5a,0x2e,0xf0,0x65
|
| };
|
| for (int i = 0; i < 32; i++) h[i] = BASIS[i];
|
| }
|
|
|
| static void fnv256_update(uint8_t* h, const uint8_t* data, size_t len) {
|
| static const uint8_t PRIME[32] = {
|
| 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
| 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
| 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
| 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x63
|
| };
|
| for (size_t i = 0; i < len; i++) {
|
|
|
| h[31] ^= data[i];
|
|
|
| uint16_t carry = 0;
|
| for (int b = 31; b >= 0; b--) {
|
| uint16_t acc = (uint16_t)h[b] * (uint16_t)PRIME[31] + carry;
|
| h[b] = (uint8_t)(acc & 0xFF);
|
| carry = acc >> 8;
|
| }
|
| (void)carry;
|
| }
|
| }
|
|
|
| static void push_be4(uint8_t* h, uint32_t v) {
|
| uint8_t buf[4] = {
|
| (uint8_t)(v >> 24), (uint8_t)(v >> 16),
|
| (uint8_t)(v >> 8), (uint8_t)(v)
|
| };
|
| fnv256_update(h, buf, 4);
|
| }
|
|
|
| static void push_be8(uint8_t* h, uint64_t v) {
|
| uint8_t buf[8] = {
|
| (uint8_t)(v >> 56), (uint8_t)(v >> 48),
|
| (uint8_t)(v >> 40), (uint8_t)(v >> 32),
|
| (uint8_t)(v >> 24), (uint8_t)(v >> 16),
|
| (uint8_t)(v >> 8), (uint8_t)(v)
|
| };
|
| fnv256_update(h, buf, 8);
|
| }
|
|
|
| int sov_ptx_hash(const uint8_t* ptx, uint32_t ptx_len,
|
| uint32_t abi_version, uint64_t device_epoch,
|
| sov_ptx_evidence_t* ev_out) {
|
| if (!ptx || !ptx_len || !ev_out) return -1;
|
| uint8_t h[32];
|
| fnv256_init(h);
|
| push_be4(h, abi_version);
|
| push_be8(h, device_epoch);
|
| push_be4(h, ptx_len);
|
| fnv256_update(h, ptx, ptx_len);
|
| for (int i = 0; i < 32; i++) ev_out->ptx_hash[i] = h[i];
|
| ev_out->abi_version = abi_version;
|
| ev_out->device_epoch = device_epoch;
|
| ev_out->ptx_len = ptx_len;
|
| return 0;
|
| }
|
|
|
| |
| |
|
|
|
|
| static void derive_rowm_root(const sov_ptx_evidence_t* ev, uint64_t seq, uint8_t* root) {
|
| uint8_t h[32];
|
| fnv256_init(h);
|
| fnv256_update(h, ev->ptx_hash, 32);
|
| push_be4(h, ev->abi_version);
|
| push_be8(h, ev->device_epoch);
|
| push_be4(h, ev->ptx_len);
|
| push_be8(h, seq);
|
| for (int i = 0; i < 32; i++) root[i] = h[i];
|
| }
|
|
|
| static void derive_worm_receipt(const uint8_t* rowm_root, uint8_t* receipt) {
|
| uint8_t h[32];
|
| fnv256_init(h);
|
| fnv256_update(h, rowm_root, 32);
|
|
|
| uint8_t dom = 0xAB;
|
| fnv256_update(h, &dom, 1);
|
| for (int i = 0; i < 32; i++) receipt[i] = h[i];
|
| }
|
|
|
| static int bytes_eq(const uint8_t* a, const uint8_t* b, size_t n) {
|
| uint8_t acc = 0;
|
| for (size_t i = 0; i < n; i++) acc |= (uint8_t)(a[i] ^ b[i]);
|
| return acc == 0;
|
| }
|
|
|
| int sov_rowm_commit(sov_rowm_record_t* rec, const sov_ptx_evidence_t* ev) {
|
| if (!rec || !ev) return -1;
|
|
|
| if (rec->state == SOV_ROWM_COMMITTED || rec->state == SOV_ROWM_AUTHORIZED) {
|
|
|
| if (rec->evidence.device_epoch == ev->device_epoch &&
|
| bytes_eq(rec->evidence.ptx_hash, ev->ptx_hash, 32)) {
|
| return 0;
|
| }
|
|
|
| if (rec->evidence.device_epoch == ev->device_epoch) {
|
| rec->state = SOV_ROWM_CONFLICT;
|
| return -2;
|
| }
|
| }
|
|
|
| rec->evidence = *ev;
|
| rec->sequence++;
|
|
|
| derive_rowm_root(ev, rec->sequence, rec->rowm_root);
|
| derive_worm_receipt(rec->rowm_root, rec->worm_receipt);
|
| rec->state = SOV_ROWM_COMMITTED;
|
| return 0;
|
| }
|
|
|
| |
| |
|
|
|
|
| int sov_rowm_authorize_kernels(sov_rowm_record_t* rec, sov_cuda_auth_t* auth,
|
| void** handles, uint32_t count) {
|
| if (!rec || !auth || !handles) return -1;
|
| if (rec->state != SOV_ROWM_COMMITTED) return -1;
|
| if (count > SOV_ROWM_MAX_KERNELS) return -4;
|
|
|
| for (uint32_t i = 0; i < count; i++) auth->handles[i] = handles[i];
|
| auth->count = count;
|
| for (int i = 0; i < 32; i++) auth->bound_worm[i] = rec->worm_receipt[i];
|
|
|
| rec->state = SOV_ROWM_AUTHORIZED;
|
| return 0;
|
| }
|
|
|
| int sov_rowm_check_authorized(const sov_rowm_record_t* rec,
|
| const sov_cuda_auth_t* auth) {
|
| if (!rec || !auth) return -1;
|
| if (rec->state != SOV_ROWM_AUTHORIZED) return -1;
|
| if (!bytes_eq(rec->worm_receipt, auth->bound_worm, 32)) return -2;
|
| return 0;
|
| }
|
|
|