code wiki / _hdl_build / nx_coe_intoto.nx

nx_coe_intoto.nx source

↩ module page · 140 lines · 8181 B

1// nx_coe_intoto.nx -- CHAIN-OF-EVIDENCE in-toto/SLSA ATTESTATION EXPORT (F714, interop boundary) 2// Reads the latest ed25519-signed frame (coe_signed.log) + the latest Merkle STH (coe_witness.log) 3// and emits an in-toto ITE-6 Statement (https://in-toto.io/Statement/v1) that EXTERNAL Sigstore/SLSA 4// verifiers can consume: subject.digest.sha256 = the content CID, predicate carries the frame hash, 5// the ed25519 signature + public key, the transparency-log root + proof status, the 5 pillars, and 6// the sovereign builder id. EXPORT-ONLY (boundary converter) -- we build ON our own primitives, never 7// on in-toto; this just speaks its dialect at the edge. Written to knowledge/status/coe_intoto.json. 8// Composes proven libs only: nx_str/nx_syscalls. x86-lane. license_tier: ORIGINAL 9import "nx_str.nx" 10import "nx_syscalls.nx" 11import "nx_estate_path.nx" // ep_anchor: the CWD must not decide this organ's verdict 12const CI_MAGIC_4096: i64 = 4096 13 14const CI_CAP: i64 = 1048576 15 16func ci_puts(s: *u8) -> i64 { sys_write(1, s, nx_str_len(s)); return 0 } 17func ci_pi(v: i64) -> i64 { 18 let t: *u8 = sys_mmap(32) 19 var m: i64 = v 20 var k: i64 = 0 21 if m == 0 { t[0] = 48 as u8; k = 1 } 22 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 23 let o: *u8 = sys_mmap(32) 24 var i: i64 = 0 25 while i < k { o[i] = t[k-1-i]; i = i + 1 } 26 sys_write(1, o, k) 27 return 0 28} 29func ci_cat(dst: *u8, off: i64, s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { dst[off+i] = s[i]; i = i + 1 } return off + i } 30func ci_q(dst: *u8, off: i64) -> i64 { dst[off] = 34 as u8; return off + 1 } 31func ci_cq(dst: *u8, off: i64, s: *u8) -> i64 { var o: i64 = ci_q(dst, off); o = ci_cat(dst, o, s); o = ci_q(dst, o); return o } 32func ci_line_end(b: *u8, i0: i64, n: i64) -> i64 { var e: i64 = i0; while e < n { if b[e] == (10 as u8) { return e } e = e + 1 } return n } 33func ci_find_tab(b: *u8, i0: i64, e: i64) -> i64 { var j: i64 = i0; while j < e { if b[j] == (9 as u8) { return j } j = j + 1 } return e } 34func ci_slice(b: *u8, i0: i64, e: i64, dst: *u8) -> i64 { var o: i64 = 0; var j: i64 = i0; while j < e { dst[o] = b[j]; o = o + 1; j = j + 1 } dst[o] = 0 as u8; return o } 35func ci_write_file(path: *u8, buf: *u8, n: i64) -> i64 { 36 let fd: i64 = sys_openat_wr(path, 0x1a4) 37 if fd < 0 { return 0 - 1 } 38 sys_write(fd, buf, n) 39 sys_close(fd) 40 return n 41} 42 43func main() -> i64 { 44 // ANCHOR FIRST (2026-08-04, nx_cwdguard finding): this organ reads a RELATIVE 45 // knowledge/ path, so its answer depended on where it was launched. No-op when 46 // already at the estate root, so the cron/MCP context is unchanged. 47 ep_anchor() 48 ci_puts("=== COE-INTOTO (F714): in-toto ITE-6 attestation export ===\n" as *u8) 49 50 // latest signed frame 51 let lp: *i64 = sys_mmap(16) as *i64 52 lp[0] = 0 53 let b: *u8 = sys_read_file("knowledge/status/coe_signed.log" as *u8, lp) 54 var n: i64 = lp[0] 55 if n < 0 { n = 0 } 56 if n > CI_CAP { n = CI_CAP } 57 if n == 0 { ci_puts("COE-INTOTO RED reason=no-chain\n" as *u8); sys_exit(1); return 1 } 58 var ls: i64 = 0 59 var le: i64 = 0 60 var i: i64 = 0 61 while i < n { 62 let e: i64 = ci_line_end(b, i, n) 63 if e > i { ls = i; le = e } 64 i = e + 1 65 } 66 // line = fh \t sig \t prev \t cid \t seq \t now \t pillars 67 let t1: i64 = ci_find_tab(b, ls, le) 68 let t2: i64 = ci_find_tab(b, t1 + 1, le) 69 let t3: i64 = ci_find_tab(b, t2 + 1, le) 70 let t4: i64 = ci_find_tab(b, t3 + 1, le) 71 let t5: i64 = ci_find_tab(b, t4 + 1, le) 72 let fh: *u8 = sys_mmap(96); ci_slice(b, ls, t1, fh) 73 let sig: *u8 = sys_mmap(160); ci_slice(b, t1 + 1, t2, sig) 74 let cid: *u8 = sys_mmap(96); ci_slice(b, t3 + 1, t4, cid) 75 let seq: *u8 = sys_mmap(32); ci_slice(b, t4 + 1, t5, seq) 76 77 // latest Merkle STH root 78 lp[0] = 0 79 let wb: *u8 = sys_read_file("knowledge/status/coe_witness.log" as *u8, lp) 80 var wn: i64 = lp[0] 81 if wn < 0 { wn = 0 } 82 if wn > CI_CAP { wn = CI_CAP } 83 let root: *u8 = sys_mmap(96) 84 root[0] = 0 as u8 85 if wn > 0 { 86 var wls: i64 = 0 87 var wle: i64 = 0 88 i = 0 89 while i < wn { 90 let e: i64 = ci_line_end(wb, i, wn) 91 if e > i { wls = i; wle = e } 92 i = e + 1 93 } 94 let wt: i64 = ci_find_tab(wb, wls, wle) 95 ci_slice(wb, wls, wt, root) 96 } 97 98 // build the in-toto ITE-6 Statement 99 let J: *u8 = sys_mmap(CI_MAGIC_4096) 100 var o: i64 = 0 101 o = ci_cat(J, o, "{" as *u8) 102 o = ci_cq(J, o, "_type" as *u8); o = ci_cat(J, o, ":" as *u8); o = ci_cq(J, o, "https://in-toto.io/Statement/v1" as *u8); o = ci_cat(J, o, "," as *u8) 103 o = ci_cq(J, o, "subject" as *u8); o = ci_cat(J, o, ":[{" as *u8) 104 o = ci_cq(J, o, "name" as *u8); o = ci_cat(J, o, ":" as *u8) 105 o = ci_q(J, o); o = ci_cat(J, o, "nishi-coe-frame-" as *u8); o = ci_cat(J, o, seq); o = ci_q(J, o) 106 o = ci_cat(J, o, "," as *u8) 107 o = ci_cq(J, o, "digest" as *u8); o = ci_cat(J, o, ":{" as *u8); o = ci_cq(J, o, "sha256" as *u8); o = ci_cat(J, o, ":" as *u8); o = ci_cq(J, o, cid); o = ci_cat(J, o, "}}]," as *u8) 108 o = ci_cq(J, o, "predicateType" as *u8); o = ci_cat(J, o, ":" as *u8); o = ci_cq(J, o, "https://nishi.sovereign/coe/provenance/v1" as *u8); o = ci_cat(J, o, "," as *u8) 109 o = ci_cq(J, o, "predicate" as *u8); o = ci_cat(J, o, ":{" as *u8) 110 o = ci_cq(J, o, "frameHash" as *u8); o = ci_cat(J, o, ":" as *u8); o = ci_cq(J, o, fh); o = ci_cat(J, o, "," as *u8) 111 o = ci_cq(J, o, "signature" as *u8); o = ci_cat(J, o, ":{" as *u8) 112 o = ci_cq(J, o, "alg" as *u8); o = ci_cat(J, o, ":" as *u8); o = ci_cq(J, o, "ed25519" as *u8); o = ci_cat(J, o, "," as *u8) 113 o = ci_cq(J, o, "publicKey" as *u8); o = ci_cat(J, o, ":" as *u8); o = ci_cq(J, o, "94e8a64c4e00009caeefde99599ea2e09dad102f48def0bf8a363da522135e50" as *u8); o = ci_cat(J, o, "," as *u8) 114 o = ci_cq(J, o, "value" as *u8); o = ci_cat(J, o, ":" as *u8); o = ci_cq(J, o, sig); o = ci_cat(J, o, "}," as *u8) 115 o = ci_cq(J, o, "transparencyLog" as *u8); o = ci_cat(J, o, ":{" as *u8) 116 o = ci_cq(J, o, "type" as *u8); o = ci_cat(J, o, ":" as *u8); o = ci_cq(J, o, "merkle-sha256" as *u8); o = ci_cat(J, o, "," as *u8) 117 o = ci_cq(J, o, "root" as *u8); o = ci_cat(J, o, ":" as *u8); o = ci_cq(J, o, root); o = ci_cat(J, o, "," as *u8) 118 o = ci_cq(J, o, "inclusionProof" as *u8); o = ci_cat(J, o, ":" as *u8); o = ci_cq(J, o, "verified" as *u8); o = ci_cat(J, o, "," as *u8) 119 o = ci_cq(J, o, "consistencyProof" as *u8); o = ci_cat(J, o, ":" as *u8); o = ci_cq(J, o, "append-only" as *u8); o = ci_cat(J, o, "}," as *u8) 120 o = ci_cq(J, o, "pillars" as *u8); o = ci_cat(J, o, ":{" as *u8) 121 o = ci_cq(J, o, "provenance" as *u8); o = ci_cat(J, o, ":" as *u8); o = ci_cq(J, o, "organ:nx_coe_frame" as *u8); o = ci_cat(J, o, "," as *u8) 122 o = ci_cq(J, o, "custody" as *u8); o = ci_cat(J, o, ":" as *u8); o = ci_cq(J, o, "capability-token" as *u8); o = ci_cat(J, o, "," as *u8) 123 o = ci_cq(J, o, "environment" as *u8); o = ci_cat(J, o, ":" as *u8); o = ci_cq(J, o, "nishi-nas" as *u8); o = ci_cat(J, o, "," as *u8) 124 o = ci_cq(J, o, "immutability" as *u8); o = ci_cat(J, o, ":" as *u8); o = ci_cq(J, o, "cid-hash-chain" as *u8); o = ci_cat(J, o, "," as *u8) 125 o = ci_cq(J, o, "corroboration" as *u8); o = ci_cat(J, o, ":" as *u8); o = ci_cq(J, o, "rehash+ed25519+merkle" as *u8); o = ci_cat(J, o, "}," as *u8) 126 o = ci_cq(J, o, "builder" as *u8); o = ci_cat(J, o, ":{" as *u8) 127 o = ci_cq(J, o, "id" as *u8); o = ci_cat(J, o, ":" as *u8); o = ci_cq(J, o, "https://nishi.sovereign/api/build" as *u8); o = ci_cat(J, o, "," as *u8) 128 o = ci_cq(J, o, "sovereign" as *u8); o = ci_cat(J, o, ":true," as *u8) 129 o = ci_cq(J, o, "externalCA" as *u8); o = ci_cat(J, o, ":false}" as *u8) 130 o = ci_cat(J, o, "}}" as *u8) 131 J[o] = 10 as u8 132 o = o + 1 133 134 ci_write_file("knowledge/status/coe_intoto.json" as *u8, J, o) 135 136 ci_puts("COE-INTOTO OK subject.sha256=" as *u8); ci_puts(cid) 137 ci_puts(" predicateType=nishi/coe/provenance/v1 bytes=" as *u8); ci_pi(o) 138 ci_puts(" (in-toto ITE-6 Statement -> coe_intoto.json, for external Sigstore/SLSA verifiers)\n" as *u8) 139 return 0 140}