code wiki / _hdl_build / nx_trust_store_corroborated.nx
nx_trust_store_corroborated.nx source
↩ module page · 65 lines · 3716 B
1// nx_trust_store_corroborated.nx -- the SPORE builds its whole trust store by CORROBORATION (operator: "build
2// from the hardware layer up so the spore can get this... keep helping them build capabilities"). This is the
3// store-building PASS on top of nx_trust_corroborate: scan M candidate roots, each presented by N independent
4// sources, and ADMIT a root into the store ONLY IF >= K sources agree on bytes the team hashed itself. Hearsay
5// (lone source) and poison (a tampered presentation) are rejected. The admitted index list is what the caller
6// then parses (nx_x509) + adds (trust_store_add) so nx_https_get can validate real chains. The DER bytes come
7// from any (untrusted) source -- the NAS local store, an HTTP-served CA root via the team's own nx_browse_text,
8// a mirror -- because trust is on the corroboration, not the transport. license_tier: ORIGINAL
9import "nx_trust_corroborate.nx"
10import "nx_syscalls.nx"
11
12// build the ADMITTED root set. roots_base packs M roots; root r's N source-presentations start at
13// roots_base + r*(n_sources*der_stride), each presentation der_stride apart, der_len bytes hashed.
14// fills admitted_idx[0..count) with the indices of corroborated roots; returns count.
15func tsc_build(roots_base: *u8, m_roots: i64, n_sources: i64, der_stride: i64, der_len: i64, k: i64, admitted_idx: *i64) -> i64 {
16 var count: i64 = 0; var r: i64 = 0
17 while r < m_roots {
18 let src: *u8 = roots_base + r * (n_sources * der_stride)
19 if tc_admit_root(src, der_stride, der_len, n_sources, k) == 1 {
20 admitted_idx[count] = r; count = count + 1
21 }
22 r = r + 1
23 }
24 return count
25}
26
27// build the ADMITTED set AND name the SOURCE whose bytes must be parsed for each root.
28// ADDED 2026-08-06 (debt 1786068026): tsc_build above returns only the ROOT index, so the caller had
29// to choose a presentation itself -- and the obvious choice is index 0, which under the source-0
30// admission bug was exactly the poison. Fixing tc_admit_root to count the majority does NOT fix the
31// install if the caller still picks its own bytes; it merely gives the poison a quorum's blessing.
32// AN ADMISSION DECISION THAT DOES NOT ALSO NAME THE BYTES IT ADMITTED IS ONLY HALF A DECISION.
33// admitted_src[i] = the source index holding the majority view of admitted_idx[i]. Parse THAT one.
34func tsc_build_sourced(roots_base: *u8, m_roots: i64, n_sources: i64, der_stride: i64, der_len: i64,
35 k: i64, admitted_idx: *i64, admitted_src: *i64) -> i64 {
36 var count: i64 = 0
37 var r: i64 = 0
38 while r < m_roots {
39 let src: *u8 = roots_base + r * (n_sources * der_stride)
40 let si: i64 = tc_admit_root_index(src, der_stride, der_len, n_sources, k)
41 if si >= 0 {
42 admitted_idx[count] = r
43 admitted_src[count] = si
44 count = count + 1
45 }
46 r = r + 1
47 }
48 return count
49}
50
51// SOUNDNESS gate: every admitted root must have had >= K independent corroboration (no hearsay/poison slipped in).
52// the builder is only allowed to hand the store to nx_https_get if this holds.
53func tsc_all_corroborated(roots_base: *u8, admitted_idx: *i64, count: i64, n_sources: i64, der_stride: i64, der_len: i64, k: i64) -> i64 {
54 var i: i64 = 0
55 while i < count {
56 let r: i64 = admitted_idx[i]
57 let src: *u8 = roots_base + r * (n_sources * der_stride)
58 if tc_corroboration_strength(src, der_stride, der_len, n_sources) < k { return 0 }
59 i = i + 1
60 }
61 return 1
62}
63
64// COVERAGE: did we admit at least enough roots to be useful? (a store of 0 roots trusts nothing -> fail closed.)
65func tsc_usable(count: i64) -> i64 { if count > 0 { return 1 } return 0 }