File size: 6,966 Bytes
9425aed | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | #include "rowm_cuda_validation.h"
#include <stdint.h>
#include <stddef.h>
typedef struct {
sov_rowm_commit_cuda_validation_fn commit_fn;
void* rowm_context;
sov_cuda_validation_evidence_t evidence;
sov_rowm_cuda_validation_commit_t commit;
int authorized;
} sov_cuda_validation_state_t;
static sov_cuda_validation_state_t g_validation;
static void zero_bytes(void* dst, size_t size) {
uint8_t* b = (uint8_t*)dst;
size_t i;
for (i = 0; i < size; ++i) b[i] = 0;
}
static int bytes_are_nonzero(const uint8_t* bytes, size_t size) {
uint8_t acc = 0;
size_t i;
if (!bytes) return 0;
for (i = 0; i < size; ++i) acc = (uint8_t)(acc | bytes[i]);
return acc != 0;
}
static int bytes_equal(const uint8_t* left, const uint8_t* right, size_t size) {
size_t i;
if (!left || !right) return 0;
for (i = 0; i < size; ++i) if (left[i] != right[i]) return 0;
return 1;
}
static int evidence_is_valid(const sov_cuda_validation_evidence_t* ev) {
if (!ev
|| ev->schema_version != SOV_CUDA_VALIDATION_SCHEMA_VERSION
|| ev->backend_id != SOV_CUDA_BACKEND_SOV_RTX
|| ev->driver_version == 0
|| ev->compute_capability_major == 0
|| ev->ptx_target == 0
|| ev->kernel_abi_version != SOV_CUDA_KERNEL_ABI_VERSION
|| ev->scalar_storage_bits != 16u
|| ev->accumulator_storage_bits != 32u
|| ev->kv_layout_version != SOV_CUDA_KV_LAYOUT_VERSION
|| ev->validation_result != 0
|| (ev->validation_flags & SOV_CUDA_VALIDATION_REQUIRED_FLAGS)
!= SOV_CUDA_VALIDATION_REQUIRED_FLAGS
|| (ev->resolved_kernel_mask & SOV_CUDA_REQUIRED_KERNEL_MASK)
!= SOV_CUDA_REQUIRED_KERNEL_MASK
|| ev->cuda_context_generation == 0
|| !bytes_are_nonzero(ev->device_uuid, sizeof(ev->device_uuid))
|| !ev->flash_ptx.bytes || ev->flash_ptx.size == 0
|| !ev->gemm_ptx.bytes || ev->gemm_ptx.size == 0) {
return 0;
}
return 1;
}
static int commit_is_valid(const sov_rowm_cuda_validation_commit_t* c) {
return c
&& c->version == SOV_ROWM_CUDA_COMMIT_VERSION
&& c->reserved == 0
&& c->validation_epoch != 0
&& bytes_are_nonzero(c->record_id, sizeof(c->record_id))
&& bytes_are_nonzero(c->committed_rowm_root, sizeof(c->committed_rowm_root))
&& bytes_are_nonzero(c->embedded_worm_receipt_hash,
sizeof(c->embedded_worm_receipt_hash));
}
static int evidence_equal(const sov_cuda_validation_evidence_t* l,
const sov_cuda_validation_evidence_t* r) {
if (!l || !r
|| l->schema_version != r->schema_version
|| l->backend_id != r->backend_id
|| l->driver_version != r->driver_version
|| l->compute_capability_major != r->compute_capability_major
|| l->compute_capability_minor != r->compute_capability_minor
|| l->ptx_target != r->ptx_target
|| l->kernel_abi_version != r->kernel_abi_version
|| l->scalar_storage_bits != r->scalar_storage_bits
|| l->accumulator_storage_bits != r->accumulator_storage_bits
|| l->kv_layout_version != r->kv_layout_version
|| l->validation_result != r->validation_result
|| l->validation_flags != r->validation_flags
|| l->resolved_kernel_mask != r->resolved_kernel_mask
|| l->cuda_context_generation != r->cuda_context_generation
|| l->flash_ptx.size != r->flash_ptx.size
|| l->gemm_ptx.size != r->gemm_ptx.size
|| !bytes_equal(l->device_uuid, r->device_uuid, sizeof(l->device_uuid))
|| !bytes_equal(l->flash_ptx.bytes, r->flash_ptx.bytes, l->flash_ptx.size)
|| !bytes_equal(l->gemm_ptx.bytes, r->gemm_ptx.bytes, l->gemm_ptx.size)) {
return 0;
}
return 1;
}
int sov_cuda_validation_bind_rowm(sov_rowm_commit_cuda_validation_fn commit_fn,
void* rowm_context) {
if (!commit_fn || !rowm_context) return SOV_CUDA_ROWM_INVALID_ARGUMENT;
if (g_validation.commit_fn) {
return (g_validation.commit_fn == commit_fn
&& g_validation.rowm_context == rowm_context)
? SOV_CUDA_ROWM_OK
: SOV_CUDA_ROWM_BIND_CONFLICT;
}
g_validation.commit_fn = commit_fn;
g_validation.rowm_context = rowm_context;
return SOV_CUDA_ROWM_OK;
}
int sov_cuda_validation_commit_rowm(const sov_cuda_validation_evidence_t* evidence) {
sov_rowm_cuda_validation_commit_t commit;
int result;
if (!g_validation.commit_fn || !g_validation.rowm_context)
return SOV_CUDA_ROWM_UNBOUND;
if (!evidence_is_valid(evidence))
return SOV_CUDA_ROWM_INVALID_ARGUMENT;
if (g_validation.authorized) {
if (evidence->cuda_context_generation
!= g_validation.evidence.cuda_context_generation) {
g_validation.authorized = 0;
zero_bytes(&g_validation.commit, sizeof(g_validation.commit));
return SOV_CUDA_ROWM_STALE_CONTEXT;
}
return evidence_equal(evidence, &g_validation.evidence)
? SOV_CUDA_ROWM_OK
: SOV_CUDA_ROWM_EVIDENCE_MISMATCH;
}
zero_bytes(&commit, sizeof(commit));
result = g_validation.commit_fn(g_validation.rowm_context, evidence, &commit);
if (result != 0) return SOV_CUDA_ROWM_COMMIT_FAILED;
if (!commit_is_valid(&commit)) return SOV_CUDA_ROWM_INVALID_PROOF;
g_validation.evidence = *evidence;
g_validation.commit = commit;
g_validation.authorized = 1;
return SOV_CUDA_ROWM_OK;
}
int sov_cuda_validation_require_authorized(uint64_t cuda_context_generation) {
if (!g_validation.authorized) return SOV_CUDA_ROWM_UNAUTHORIZED;
if (cuda_context_generation == 0
|| cuda_context_generation
!= g_validation.evidence.cuda_context_generation) {
g_validation.authorized = 0;
zero_bytes(&g_validation.commit, sizeof(g_validation.commit));
return SOV_CUDA_ROWM_STALE_CONTEXT;
}
return SOV_CUDA_ROWM_OK;
}
int sov_cuda_validation_get_commit(sov_rowm_cuda_validation_commit_t* commit_out) {
if (!commit_out) return SOV_CUDA_ROWM_INVALID_ARGUMENT;
if (!g_validation.authorized) {
zero_bytes(commit_out, sizeof(*commit_out));
return SOV_CUDA_ROWM_UNAUTHORIZED;
}
*commit_out = g_validation.commit;
return SOV_CUDA_ROWM_OK;
}
void sov_cuda_validation_clear(void) {
zero_bytes(&g_validation, sizeof(g_validation));
}
|