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}